good morning!!!!
Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
B
bor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Harbor Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
open
bor
Commits
04fcae20
Commit
04fcae20
authored
Apr 10, 2017
by
Péter Szilágyi
Committed by
Felix Lange
Apr 10, 2017
Browse files
Options
Downloads
Patches
Plain Diff
p2p: if no nodes are connected, attempt dialing bootnodes (#13874)
parent
542e42b2
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
p2p/dial.go
+26
-2
26 additions, 2 deletions
p2p/dial.go
p2p/dial_test.go
+94
-6
94 additions, 6 deletions
p2p/dial_test.go
p2p/server.go
+1
-1
1 addition, 1 deletion
p2p/server.go
with
121 additions
and
9 deletions
p2p/dial.go
+
26
−
2
View file @
04fcae20
...
@@ -38,6 +38,10 @@ const (
...
@@ -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
...
@@ -57,6 +61,9 @@ type dialstate struct {
...
@@ -57,6 +61,9 @@ type dialstate struct {
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
{
...
@@ -102,16 +109,18 @@ type waitExpireTask struct {
...
@@ -102,16 +109,18 @@ type waitExpireTask struct {
time
.
Duration
time
.
Duration
}
}
func
newDialState
(
static
[]
*
discover
.
Node
,
ntab
discoverTable
,
maxdyn
int
,
netrestrict
*
netutil
.
Netlist
)
*
dialstate
{
func
newDialState
(
static
[]
*
discover
.
Node
,
bootnodes
[]
*
discover
.
Node
,
ntab
discoverTable
,
maxdyn
int
,
netrestrict
*
netutil
.
Netlist
)
*
dialstate
{
s
:=
&
dialstate
{
s
:=
&
dialstate
{
maxDynDials
:
maxdyn
,
maxDynDials
:
maxdyn
,
ntab
:
ntab
,
ntab
:
ntab
,
netrestrict
:
netrestrict
,
netrestrict
:
netrestrict
,
static
:
make
(
map
[
discover
.
NodeID
]
*
dialTask
),
static
:
make
(
map
[
discover
.
NodeID
]
*
dialTask
),
dialing
:
make
(
map
[
discover
.
NodeID
]
connFlag
),
dialing
:
make
(
map
[
discover
.
NodeID
]
connFlag
),
bootnodes
:
make
([]
*
discover
.
Node
,
len
(
bootnodes
)),
randomNodes
:
make
([]
*
discover
.
Node
,
maxdyn
/
2
),
randomNodes
:
make
([]
*
discover
.
Node
,
maxdyn
/
2
),
hist
:
new
(
dialHistory
),
hist
:
new
(
dialHistory
),
}
}
copy
(
s
.
bootnodes
,
bootnodes
)
for
_
,
n
:=
range
static
{
for
_
,
n
:=
range
static
{
s
.
addStatic
(
n
)
s
.
addStatic
(
n
)
}
}
...
@@ -130,6 +139,10 @@ func (s *dialstate) removeStatic(n *discover.Node) {
...
@@ -130,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
{
...
@@ -169,7 +182,18 @@ func (s *dialstate) newTasks(nRunning int, peers map[discover.NodeID]*Peer, now
...
@@ -169,7 +182,18 @@ func (s *dialstate) newTasks(nRunning int, peers map[discover.NodeID]*Peer, now
newtasks
=
append
(
newtasks
,
t
)
newtasks
=
append
(
newtasks
,
t
)
}
}
}
}
// 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
&&
now
.
Sub
(
s
.
start
)
>
fallbackInterval
{
bootnode
:=
s
.
bootnodes
[
0
]
s
.
bootnodes
=
append
(
s
.
bootnodes
[
:
0
],
s
.
bootnodes
[
1
:
]
...
)
s
.
bootnodes
=
append
(
s
.
bootnodes
,
bootnode
)
if
addDial
(
dynDialedConn
,
bootnode
)
{
needDynDials
--
}
}
// Use random nodes from the table for half of the necessary
// Use random nodes from the table for half of the necessary
// dynamic dials.
// dynamic dials.
randomCandidates
:=
needDynDials
/
2
randomCandidates
:=
needDynDials
/
2
...
...
This diff is collapsed.
Click to expand it.
p2p/dial_test.go
+
94
−
6
View file @
04fcae20
...
@@ -87,7 +87,7 @@ func (t fakeTable) ReadRandomNodes(buf []*discover.Node) int { return copy(buf,
...
@@ -87,7 +87,7 @@ func (t fakeTable) ReadRandomNodes(buf []*discover.Node) int { return copy(buf,
// This test checks that dynamic dials are launched from discovery results.
// This test checks that dynamic dials are launched from discovery results.
func
TestDialStateDynDial
(
t
*
testing
.
T
)
{
func
TestDialStateDynDial
(
t
*
testing
.
T
)
{
runDialTest
(
t
,
dialtest
{
runDialTest
(
t
,
dialtest
{
init
:
newDialState
(
nil
,
fakeTable
{},
5
,
nil
),
init
:
newDialState
(
nil
,
nil
,
fakeTable
{},
5
,
nil
),
rounds
:
[]
round
{
rounds
:
[]
round
{
// A discovery query is launched.
// A discovery query is launched.
{
{
...
@@ -219,6 +219,94 @@ func TestDialStateDynDial(t *testing.T) {
...
@@ -219,6 +219,94 @@ func TestDialStateDynDial(t *testing.T) {
})
})
}
}
// Tests that bootnodes are dialed if no peers are connectd, but not otherwise.
func
TestDialStateDynDialBootnode
(
t
*
testing
.
T
)
{
bootnodes
:=
[]
*
discover
.
Node
{
{
ID
:
uintID
(
1
)},
{
ID
:
uintID
(
2
)},
{
ID
:
uintID
(
3
)},
}
table
:=
fakeTable
{
{
ID
:
uintID
(
4
)},
{
ID
:
uintID
(
5
)},
{
ID
:
uintID
(
6
)},
{
ID
:
uintID
(
7
)},
{
ID
:
uintID
(
8
)},
}
runDialTest
(
t
,
dialtest
{
init
:
newDialState
(
nil
,
bootnodes
,
table
,
5
,
nil
),
rounds
:
[]
round
{
// 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
)}},
},
},
// No dials succeed, 2nd bootnode is attempted
{
done
:
[]
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
)}},
},
new
:
[]
task
{
&
dialTask
{
flags
:
dynDialedConn
,
dest
:
&
discover
.
Node
{
ID
:
uintID
(
2
)}},
},
},
// No dials succeed, 3rd bootnode is attempted
{
done
:
[]
task
{
&
dialTask
{
flags
:
dynDialedConn
,
dest
:
&
discover
.
Node
{
ID
:
uintID
(
2
)}},
},
new
:
[]
task
{
&
dialTask
{
flags
:
dynDialedConn
,
dest
:
&
discover
.
Node
{
ID
:
uintID
(
3
)}},
},
},
// No dials succeed, 1st bootnode is attempted again, expired random nodes retried
{
done
:
[]
task
{
&
dialTask
{
flags
:
dynDialedConn
,
dest
:
&
discover
.
Node
{
ID
:
uintID
(
3
)}},
},
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
)}},
},
},
// Random dial succeeds, no more bootnodes are attempted
{
peers
:
[]
*
Peer
{
{
rw
:
&
conn
{
flags
:
dynDialedConn
,
id
:
uintID
(
4
)}},
},
done
:
[]
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
)}},
},
},
},
})
}
func
TestDialStateDynDialFromTable
(
t
*
testing
.
T
)
{
func
TestDialStateDynDialFromTable
(
t
*
testing
.
T
)
{
// This table always returns the same random nodes
// This table always returns the same random nodes
// in the order given below.
// in the order given below.
...
@@ -234,7 +322,7 @@ func TestDialStateDynDialFromTable(t *testing.T) {
...
@@ -234,7 +322,7 @@ func TestDialStateDynDialFromTable(t *testing.T) {
}
}
runDialTest
(
t
,
dialtest
{
runDialTest
(
t
,
dialtest
{
init
:
newDialState
(
nil
,
table
,
10
,
nil
),
init
:
newDialState
(
nil
,
nil
,
table
,
10
,
nil
),
rounds
:
[]
round
{
rounds
:
[]
round
{
// 5 out of 8 of the nodes returned by ReadRandomNodes are dialed.
// 5 out of 8 of the nodes returned by ReadRandomNodes are dialed.
{
{
...
@@ -332,7 +420,7 @@ func TestDialStateNetRestrict(t *testing.T) {
...
@@ -332,7 +420,7 @@ func TestDialStateNetRestrict(t *testing.T) {
restrict
.
Add
(
"127.0.2.0/24"
)
restrict
.
Add
(
"127.0.2.0/24"
)
runDialTest
(
t
,
dialtest
{
runDialTest
(
t
,
dialtest
{
init
:
newDialState
(
nil
,
table
,
10
,
restrict
),
init
:
newDialState
(
nil
,
nil
,
table
,
10
,
restrict
),
rounds
:
[]
round
{
rounds
:
[]
round
{
{
{
new
:
[]
task
{
new
:
[]
task
{
...
@@ -355,7 +443,7 @@ func TestDialStateStaticDial(t *testing.T) {
...
@@ -355,7 +443,7 @@ func TestDialStateStaticDial(t *testing.T) {
}
}
runDialTest
(
t
,
dialtest
{
runDialTest
(
t
,
dialtest
{
init
:
newDialState
(
wantStatic
,
fakeTable
{},
0
,
nil
),
init
:
newDialState
(
wantStatic
,
nil
,
fakeTable
{},
0
,
nil
),
rounds
:
[]
round
{
rounds
:
[]
round
{
// Static dials are launched for the nodes that
// Static dials are launched for the nodes that
// aren't yet connected.
// aren't yet connected.
...
@@ -436,7 +524,7 @@ func TestDialStateCache(t *testing.T) {
...
@@ -436,7 +524,7 @@ func TestDialStateCache(t *testing.T) {
}
}
runDialTest
(
t
,
dialtest
{
runDialTest
(
t
,
dialtest
{
init
:
newDialState
(
wantStatic
,
fakeTable
{},
0
,
nil
),
init
:
newDialState
(
wantStatic
,
nil
,
fakeTable
{},
0
,
nil
),
rounds
:
[]
round
{
rounds
:
[]
round
{
// Static dials are launched for the nodes that
// Static dials are launched for the nodes that
// aren't yet connected.
// aren't yet connected.
...
@@ -498,7 +586,7 @@ func TestDialStateCache(t *testing.T) {
...
@@ -498,7 +586,7 @@ func TestDialStateCache(t *testing.T) {
func
TestDialResolve
(
t
*
testing
.
T
)
{
func
TestDialResolve
(
t
*
testing
.
T
)
{
resolved
:=
discover
.
NewNode
(
uintID
(
1
),
net
.
IP
{
127
,
0
,
55
,
234
},
3333
,
4444
)
resolved
:=
discover
.
NewNode
(
uintID
(
1
),
net
.
IP
{
127
,
0
,
55
,
234
},
3333
,
4444
)
table
:=
&
resolveMock
{
answer
:
resolved
}
table
:=
&
resolveMock
{
answer
:
resolved
}
state
:=
newDialState
(
nil
,
table
,
0
,
nil
)
state
:=
newDialState
(
nil
,
nil
,
table
,
0
,
nil
)
// Check that the task is generated with an incomplete ID.
// Check that the task is generated with an incomplete ID.
dest
:=
discover
.
NewNode
(
uintID
(
1
),
nil
,
0
,
0
)
dest
:=
discover
.
NewNode
(
uintID
(
1
),
nil
,
0
,
0
)
...
...
This diff is collapsed.
Click to expand it.
p2p/server.go
+
1
−
1
View file @
04fcae20
...
@@ -396,7 +396,7 @@ func (srv *Server) Start() (err error) {
...
@@ -396,7 +396,7 @@ func (srv *Server) Start() (err error) {
if
!
srv
.
Discovery
{
if
!
srv
.
Discovery
{
dynPeers
=
0
dynPeers
=
0
}
}
dialer
:=
newDialState
(
srv
.
StaticNodes
,
srv
.
ntab
,
dynPeers
,
srv
.
NetRestrict
)
dialer
:=
newDialState
(
srv
.
StaticNodes
,
srv
.
BootstrapNodes
,
srv
.
ntab
,
dynPeers
,
srv
.
NetRestrict
)
// handshake
// handshake
srv
.
ourHandshake
=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
Name
:
srv
.
Name
,
ID
:
discover
.
PubkeyID
(
&
srv
.
PrivateKey
.
PublicKey
)}
srv
.
ourHandshake
=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
Name
:
srv
.
Name
,
ID
:
discover
.
PubkeyID
(
&
srv
.
PrivateKey
.
PublicKey
)}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment