Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
4d5a719f
Commit
4d5a719f
authored
May 04, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd, eth, p2p: introduce pending peer cli arg, add tests
parent
af932177
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
170 additions
and
19 deletions
+170
-19
main.go
cmd/geth/main.go
+1
-0
main.go
cmd/mist/main.go
+1
-0
flags.go
cmd/utils/flags.go
+6
-0
backend.go
eth/backend.go
+14
-12
server.go
p2p/server.go
+18
-7
server_test.go
p2p/server_test.go
+130
-0
No files found.
cmd/geth/main.go
View file @
4d5a719f
...
@@ -242,6 +242,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
...
@@ -242,6 +242,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
utils
.
JSpathFlag
,
utils
.
JSpathFlag
,
utils
.
ListenPortFlag
,
utils
.
ListenPortFlag
,
utils
.
MaxPeersFlag
,
utils
.
MaxPeersFlag
,
utils
.
MaxPendingPeersFlag
,
utils
.
EtherbaseFlag
,
utils
.
EtherbaseFlag
,
utils
.
MinerThreadsFlag
,
utils
.
MinerThreadsFlag
,
utils
.
MiningEnabledFlag
,
utils
.
MiningEnabledFlag
,
...
...
cmd/mist/main.go
View file @
4d5a719f
...
@@ -75,6 +75,7 @@ func init() {
...
@@ -75,6 +75,7 @@ func init() {
utils
.
LogFileFlag
,
utils
.
LogFileFlag
,
utils
.
LogLevelFlag
,
utils
.
LogLevelFlag
,
utils
.
MaxPeersFlag
,
utils
.
MaxPeersFlag
,
utils
.
MaxPendingPeersFlag
,
utils
.
MinerThreadsFlag
,
utils
.
MinerThreadsFlag
,
utils
.
NATFlag
,
utils
.
NATFlag
,
utils
.
NodeKeyFileFlag
,
utils
.
NodeKeyFileFlag
,
...
...
cmd/utils/flags.go
View file @
4d5a719f
...
@@ -197,6 +197,11 @@ var (
...
@@ -197,6 +197,11 @@ var (
Usage
:
"Maximum number of network peers (network disabled if set to 0)"
,
Usage
:
"Maximum number of network peers (network disabled if set to 0)"
,
Value
:
16
,
Value
:
16
,
}
}
MaxPendingPeersFlag
=
cli
.
IntFlag
{
Name
:
"maxpendpeers"
,
Usage
:
"Maximum number of pending connection attempts (defaults used if set to 0)"
,
Value
:
0
,
}
ListenPortFlag
=
cli
.
IntFlag
{
ListenPortFlag
=
cli
.
IntFlag
{
Name
:
"port"
,
Name
:
"port"
,
Usage
:
"Network listening port"
,
Usage
:
"Network listening port"
,
...
@@ -286,6 +291,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
...
@@ -286,6 +291,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
AccountManager
:
GetAccountManager
(
ctx
),
AccountManager
:
GetAccountManager
(
ctx
),
VmDebug
:
ctx
.
GlobalBool
(
VMDebugFlag
.
Name
),
VmDebug
:
ctx
.
GlobalBool
(
VMDebugFlag
.
Name
),
MaxPeers
:
ctx
.
GlobalInt
(
MaxPeersFlag
.
Name
),
MaxPeers
:
ctx
.
GlobalInt
(
MaxPeersFlag
.
Name
),
MaxPendingPeers
:
ctx
.
GlobalInt
(
MaxPendingPeersFlag
.
Name
),
Port
:
ctx
.
GlobalString
(
ListenPortFlag
.
Name
),
Port
:
ctx
.
GlobalString
(
ListenPortFlag
.
Name
),
NAT
:
GetNAT
(
ctx
),
NAT
:
GetNAT
(
ctx
),
NatSpec
:
ctx
.
GlobalBool
(
NatspecEnabledFlag
.
Name
),
NatSpec
:
ctx
.
GlobalBool
(
NatspecEnabledFlag
.
Name
),
...
...
eth/backend.go
View file @
4d5a719f
...
@@ -60,8 +60,9 @@ type Config struct {
...
@@ -60,8 +60,9 @@ type Config struct {
VmDebug
bool
VmDebug
bool
NatSpec
bool
NatSpec
bool
MaxPeers
int
MaxPeers
int
Port
string
MaxPendingPeers
int
Port
string
// Space-separated list of discovery node URLs
// Space-separated list of discovery node URLs
BootNodes
string
BootNodes
string
...
@@ -280,16 +281,17 @@ func New(config *Config) (*Ethereum, error) {
...
@@ -280,16 +281,17 @@ func New(config *Config) (*Ethereum, error) {
protocols
=
append
(
protocols
,
eth
.
whisper
.
Protocol
())
protocols
=
append
(
protocols
,
eth
.
whisper
.
Protocol
())
}
}
eth
.
net
=
&
p2p
.
Server
{
eth
.
net
=
&
p2p
.
Server
{
PrivateKey
:
netprv
,
PrivateKey
:
netprv
,
Name
:
config
.
Name
,
Name
:
config
.
Name
,
MaxPeers
:
config
.
MaxPeers
,
MaxPeers
:
config
.
MaxPeers
,
Protocols
:
protocols
,
MaxPendingPeers
:
config
.
MaxPendingPeers
,
NAT
:
config
.
NAT
,
Protocols
:
protocols
,
NoDial
:
!
config
.
Dial
,
NAT
:
config
.
NAT
,
BootstrapNodes
:
config
.
parseBootNodes
(),
NoDial
:
!
config
.
Dial
,
StaticNodes
:
config
.
parseNodes
(
staticNodes
),
BootstrapNodes
:
config
.
parseBootNodes
(),
TrustedNodes
:
config
.
parseNodes
(
trustedNodes
),
StaticNodes
:
config
.
parseNodes
(
staticNodes
),
NodeDatabase
:
nodeDb
,
TrustedNodes
:
config
.
parseNodes
(
trustedNodes
),
NodeDatabase
:
nodeDb
,
}
}
if
len
(
config
.
Port
)
>
0
{
if
len
(
config
.
Port
)
>
0
{
eth
.
net
.
ListenAddr
=
":"
+
config
.
Port
eth
.
net
.
ListenAddr
=
":"
+
config
.
Port
...
...
p2p/server.go
View file @
4d5a719f
...
@@ -22,9 +22,7 @@ const (
...
@@ -22,9 +22,7 @@ const (
refreshPeersInterval
=
30
*
time
.
Second
refreshPeersInterval
=
30
*
time
.
Second
staticPeerCheckInterval
=
15
*
time
.
Second
staticPeerCheckInterval
=
15
*
time
.
Second
// This is the maximum number of inbound connection
// Maximum number of concurrently handshaking inbound connections.
// that are allowed to linger between 'accepted' and
// 'added as peer'.
maxAcceptConns
=
10
maxAcceptConns
=
10
// Maximum number of concurrently dialing outbound connections.
// Maximum number of concurrently dialing outbound connections.
...
@@ -55,6 +53,11 @@ type Server struct {
...
@@ -55,6 +53,11 @@ type Server struct {
// connected. It must be greater than zero.
// connected. It must be greater than zero.
MaxPeers
int
MaxPeers
int
// MaxPendingPeers is the maximum number of peers that can be pending in the
// handshake phase, counted separately for inbound and outbound connections.
// Zero defaults to preset values.
MaxPendingPeers
int
// Name sets the node name of this server.
// Name sets the node name of this server.
// Use common.MakeName to create a name that follows existing conventions.
// Use common.MakeName to create a name that follows existing conventions.
Name
string
Name
string
...
@@ -334,8 +337,12 @@ func (srv *Server) listenLoop() {
...
@@ -334,8 +337,12 @@ func (srv *Server) listenLoop() {
// This channel acts as a semaphore limiting
// This channel acts as a semaphore limiting
// active inbound connections that are lingering pre-handshake.
// active inbound connections that are lingering pre-handshake.
// If all slots are taken, no further connections are accepted.
// If all slots are taken, no further connections are accepted.
slots
:=
make
(
chan
struct
{},
maxAcceptConns
)
tokens
:=
maxAcceptConns
for
i
:=
0
;
i
<
maxAcceptConns
;
i
++
{
if
srv
.
MaxPendingPeers
>
0
{
tokens
=
srv
.
MaxPendingPeers
}
slots
:=
make
(
chan
struct
{},
tokens
)
for
i
:=
0
;
i
<
tokens
;
i
++
{
slots
<-
struct
{}{}
slots
<-
struct
{}{}
}
}
...
@@ -405,8 +412,12 @@ func (srv *Server) dialLoop() {
...
@@ -405,8 +412,12 @@ func (srv *Server) dialLoop() {
defer
refresh
.
Stop
()
defer
refresh
.
Stop
()
// Limit the number of concurrent dials
// Limit the number of concurrent dials
slots
:=
make
(
chan
struct
{},
maxDialingConns
)
tokens
:=
maxAcceptConns
for
i
:=
0
;
i
<
maxDialingConns
;
i
++
{
if
srv
.
MaxPendingPeers
>
0
{
tokens
=
srv
.
MaxPendingPeers
}
slots
:=
make
(
chan
struct
{},
tokens
)
for
i
:=
0
;
i
<
tokens
;
i
++
{
slots
<-
struct
{}{}
slots
<-
struct
{}{}
}
}
dial
:=
func
(
dest
*
discover
.
Node
)
{
dial
:=
func
(
dest
*
discover
.
Node
)
{
...
...
p2p/server_test.go
View file @
4d5a719f
...
@@ -369,6 +369,136 @@ func TestServerTrustedPeers(t *testing.T) {
...
@@ -369,6 +369,136 @@ func TestServerTrustedPeers(t *testing.T) {
}
}
}
}
// Tests that a failed dial will temporarily throttle a peer.
func
TestServerMaxPendingDials
(
t
*
testing
.
T
)
{
defer
testlog
(
t
)
.
detach
()
// Start a simple test server
server
:=
&
Server
{
ListenAddr
:
"127.0.0.1:0"
,
PrivateKey
:
newkey
(),
MaxPeers
:
10
,
MaxPendingPeers
:
1
,
}
if
err
:=
server
.
Start
();
err
!=
nil
{
t
.
Fatal
(
"failed to start test server: %v"
,
err
)
}
defer
server
.
Stop
()
// Simulate two separate remote peers
peers
:=
make
(
chan
*
discover
.
Node
,
2
)
conns
:=
make
(
chan
net
.
Conn
,
2
)
for
i
:=
0
;
i
<
2
;
i
++
{
listener
,
err
:=
net
.
Listen
(
"tcp"
,
"127.0.0.1:0"
)
if
err
!=
nil
{
t
.
Fatalf
(
"listener %d: failed to setup: %v"
,
i
,
err
)
}
defer
listener
.
Close
()
addr
:=
listener
.
Addr
()
.
(
*
net
.
TCPAddr
)
peers
<-
&
discover
.
Node
{
ID
:
discover
.
PubkeyID
(
&
newkey
()
.
PublicKey
),
IP
:
addr
.
IP
,
TCP
:
uint16
(
addr
.
Port
),
}
go
func
()
{
conn
,
err
:=
listener
.
Accept
()
if
err
==
nil
{
conns
<-
conn
}
}()
}
// Request a dial for both peers
go
func
()
{
for
i
:=
0
;
i
<
2
;
i
++
{
server
.
staticDial
<-
<-
peers
// hack piggybacking the static implementation
}
}()
// Make sure only one outbound connection goes through
var
conn
net
.
Conn
select
{
case
conn
=
<-
conns
:
case
<-
time
.
After
(
100
*
time
.
Millisecond
)
:
t
.
Fatalf
(
"first dial timeout"
)
}
select
{
case
conn
=
<-
conns
:
t
.
Fatalf
(
"second dial completed prematurely"
)
case
<-
time
.
After
(
100
*
time
.
Millisecond
)
:
}
// Finish the first dial, check the second
conn
.
Close
()
select
{
case
conn
=
<-
conns
:
conn
.
Close
()
case
<-
time
.
After
(
100
*
time
.
Millisecond
)
:
t
.
Fatalf
(
"second dial timeout"
)
}
}
func
TestServerMaxPendingAccepts
(
t
*
testing
.
T
)
{
defer
testlog
(
t
)
.
detach
()
// Start a test server and a peer sink for synchronization
started
:=
make
(
chan
*
Peer
)
server
:=
&
Server
{
ListenAddr
:
"127.0.0.1:0"
,
PrivateKey
:
newkey
(),
MaxPeers
:
10
,
MaxPendingPeers
:
1
,
NoDial
:
true
,
newPeerHook
:
func
(
p
*
Peer
)
{
started
<-
p
},
}
if
err
:=
server
.
Start
();
err
!=
nil
{
t
.
Fatal
(
"failed to start test server: %v"
,
err
)
}
defer
server
.
Stop
()
// Try and connect to the server on multiple threads concurrently
conns
:=
make
([]
net
.
Conn
,
2
)
for
i
:=
0
;
i
<
2
;
i
++
{
dialer
:=
&
net
.
Dialer
{
Deadline
:
time
.
Now
()
.
Add
(
3
*
time
.
Second
)}
conn
,
err
:=
dialer
.
Dial
(
"tcp"
,
server
.
ListenAddr
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to dial server: %v"
,
err
)
}
conns
[
i
]
=
conn
}
// Check that a handshake on the second doesn't pass
go
func
()
{
key
:=
newkey
()
shake
:=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
ID
:
discover
.
PubkeyID
(
&
key
.
PublicKey
)}
if
_
,
err
:=
setupConn
(
conns
[
1
],
key
,
shake
,
server
.
Self
(),
false
,
server
.
trustedNodes
);
err
!=
nil
{
t
.
Fatalf
(
"failed to run handshake: %v"
,
err
)
}
}()
select
{
case
<-
started
:
t
.
Fatalf
(
"handshake on second connection accepted"
)
case
<-
time
.
After
(
100
*
time
.
Millisecond
)
:
}
// Shake on first, check that both go through
go
func
()
{
key
:=
newkey
()
shake
:=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
ID
:
discover
.
PubkeyID
(
&
key
.
PublicKey
)}
if
_
,
err
:=
setupConn
(
conns
[
0
],
key
,
shake
,
server
.
Self
(),
false
,
server
.
trustedNodes
);
err
!=
nil
{
t
.
Fatalf
(
"failed to run handshake: %v"
,
err
)
}
}()
for
i
:=
0
;
i
<
2
;
i
++
{
select
{
case
<-
started
:
case
<-
time
.
After
(
100
*
time
.
Millisecond
)
:
t
.
Fatalf
(
"peer %d: handshake timeout"
,
i
)
}
}
}
func
newkey
()
*
ecdsa
.
PrivateKey
{
func
newkey
()
*
ecdsa
.
PrivateKey
{
key
,
err
:=
crypto
.
GenerateKey
()
key
,
err
:=
crypto
.
GenerateKey
()
if
err
!=
nil
{
if
err
!=
nil
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment