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
de0549fa
Commit
de0549fa
authored
Apr 29, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd/geth, cmd/mist, cmd/utils, eth, p2p: support trusted peers
parent
3fef6019
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
146 additions
and
27 deletions
+146
-27
admin.go
cmd/geth/admin.go
+3
-3
main.go
cmd/geth/main.go
+2
-1
main.go
cmd/mist/main.go
+1
-1
ui_lib.go
cmd/mist/ui_lib.go
+2
-2
flags.go
cmd/utils/flags.go
+8
-2
backend.go
eth/backend.go
+52
-4
server.go
p2p/server.go
+77
-13
server_test.go
p2p/server_test.go
+1
-1
No files found.
cmd/geth/admin.go
View file @
de0549fa
...
...
@@ -25,7 +25,7 @@ func (js *jsre) adminBindings() {
js
.
re
.
Set
(
"admin"
,
struct
{}{})
t
,
_
:=
js
.
re
.
Get
(
"admin"
)
admin
:=
t
.
Object
()
admin
.
Set
(
"
suggestPeer"
,
js
.
sugge
stPeer
)
admin
.
Set
(
"
trustPeer"
,
js
.
tru
stPeer
)
admin
.
Set
(
"startRPC"
,
js
.
startRPC
)
admin
.
Set
(
"stopRPC"
,
js
.
stopRPC
)
admin
.
Set
(
"nodeInfo"
,
js
.
nodeInfo
)
...
...
@@ -243,13 +243,13 @@ func (js *jsre) stopRPC(call otto.FunctionCall) otto.Value {
return
otto
.
FalseValue
()
}
func
(
js
*
jsre
)
sugge
stPeer
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
tru
stPeer
(
call
otto
.
FunctionCall
)
otto
.
Value
{
nodeURL
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
err
=
js
.
ethereum
.
Sugge
stPeer
(
nodeURL
)
err
=
js
.
ethereum
.
Tru
stPeer
(
nodeURL
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
...
...
cmd/geth/main.go
View file @
de0549fa
...
...
@@ -232,7 +232,8 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
utils
.
IdentityFlag
,
utils
.
UnlockedAccountFlag
,
utils
.
PasswordFileFlag
,
utils
.
BootnodesFlag
,
utils
.
BootNodesFlag
,
utils
.
TrustedNodesFlag
,
utils
.
DataDirFlag
,
utils
.
BlockchainVersionFlag
,
utils
.
JSpathFlag
,
...
...
cmd/mist/main.go
View file @
de0549fa
...
...
@@ -69,7 +69,7 @@ func init() {
assetPathFlag
,
rpcCorsFlag
,
utils
.
Boot
n
odesFlag
,
utils
.
Boot
N
odesFlag
,
utils
.
DataDirFlag
,
utils
.
ListenPortFlag
,
utils
.
LogFileFlag
,
...
...
cmd/mist/ui_lib.go
View file @
de0549fa
...
...
@@ -104,8 +104,8 @@ func (ui *UiLib) Connect(button qml.Object) {
}
func
(
ui
*
UiLib
)
ConnectToPeer
(
nodeURL
string
)
{
if
err
:=
ui
.
eth
.
Sugge
stPeer
(
nodeURL
);
err
!=
nil
{
guilogger
.
Infoln
(
"
Sugge
stPeer error: "
+
err
.
Error
())
if
err
:=
ui
.
eth
.
Tru
stPeer
(
nodeURL
);
err
!=
nil
{
guilogger
.
Infoln
(
"
Tru
stPeer error: "
+
err
.
Error
())
}
}
...
...
cmd/utils/flags.go
View file @
de0549fa
...
...
@@ -202,11 +202,16 @@ var (
Usage
:
"Network listening port"
,
Value
:
30303
,
}
Boot
n
odesFlag
=
cli
.
StringFlag
{
Boot
N
odesFlag
=
cli
.
StringFlag
{
Name
:
"bootnodes"
,
Usage
:
"Space-separated enode URLs for p2p discovery bootstrap"
,
Value
:
""
,
}
TrustedNodesFlag
=
cli
.
StringFlag
{
Name
:
"trustednodes"
,
Usage
:
"List of trusted nodes (either an enode list or path to a json file of enodes)"
,
Value
:
""
,
}
NodeKeyFileFlag
=
cli
.
StringFlag
{
Name
:
"nodekey"
,
Usage
:
"P2P node key file"
,
...
...
@@ -292,7 +297,8 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
NodeKey
:
GetNodeKey
(
ctx
),
Shh
:
ctx
.
GlobalBool
(
WhisperEnabledFlag
.
Name
),
Dial
:
true
,
BootNodes
:
ctx
.
GlobalString
(
BootnodesFlag
.
Name
),
BootNodes
:
ctx
.
GlobalString
(
BootNodesFlag
.
Name
),
TrustedNodes
:
ctx
.
GlobalString
(
TrustedNodesFlag
.
Name
),
}
}
...
...
eth/backend.go
View file @
de0549fa
...
...
@@ -2,7 +2,10 @@ package eth
import
(
"crypto/ecdsa"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
"strings"
"time"
...
...
@@ -56,10 +59,13 @@ type Config struct {
MaxPeers
int
Port
string
// This should be a space-separated list of
// discovery node URLs.
// Space-separated list of discovery node URLs
BootNodes
string
// Either a space-separated list of discovery node URLs, or a path to a json
// file containing such a list.
TrustedNodes
string
// This key is used to identify the node on the network.
// If nil, an ephemeral key is used.
NodeKey
*
ecdsa
.
PrivateKey
...
...
@@ -96,6 +102,46 @@ func (cfg *Config) parseBootNodes() []*discover.Node {
return
ns
}
// parseTrustedNodes parses a list of discovery node URLs either given literally,
// or loaded from a .json file.
func
(
cfg
*
Config
)
parseTrustedNodes
()
[]
*
discover
.
Node
{
// Short circuit if no trusted nodes were given
if
cfg
.
TrustedNodes
==
""
{
return
nil
}
// Try to interpret the trusted node config as a .json file
if
_
,
err
:=
os
.
Stat
(
cfg
.
TrustedNodes
);
err
==
nil
{
// Load the file from disk
blob
,
err
:=
ioutil
.
ReadFile
(
cfg
.
TrustedNodes
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Failed to access trusted nodes: %v"
,
err
)
return
nil
}
// Interpret the json contents
list
:=
[]
string
{}
if
err
:=
json
.
Unmarshal
(
blob
,
&
list
);
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Failed to load trusted nodes: %v"
,
err
)
return
nil
}
// Swap out the configuration for the actual nodes
cfg
.
TrustedNodes
=
strings
.
Join
(
list
,
" "
)
}
// Interpret the list as a discovery node array
var
nodes
[]
*
discover
.
Node
for
_
,
url
:=
range
strings
.
Split
(
cfg
.
TrustedNodes
,
" "
)
{
if
url
==
""
{
continue
}
node
,
err
:=
discover
.
ParseNode
(
url
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Trusted node URL %s: %v
\n
"
,
url
,
err
)
continue
}
nodes
=
append
(
nodes
,
node
)
}
return
nodes
}
func
(
cfg
*
Config
)
nodeKey
()
(
*
ecdsa
.
PrivateKey
,
error
)
{
// use explicit key from command line args if set
if
cfg
.
NodeKey
!=
nil
{
...
...
@@ -247,6 +293,7 @@ func New(config *Config) (*Ethereum, error) {
NAT
:
config
.
NAT
,
NoDial
:
!
config
.
Dial
,
BootstrapNodes
:
config
.
parseBootNodes
(),
TrustedNodes
:
config
.
parseTrustedNodes
(),
NodeDatabase
:
nodeDb
,
}
if
len
(
config
.
Port
)
>
0
{
...
...
@@ -442,12 +489,13 @@ func (s *Ethereum) StartForTest() {
s
.
txPool
.
Start
()
}
func
(
self
*
Ethereum
)
SuggestPeer
(
nodeURL
string
)
error
{
// TrustPeer injects a new node into the list of privileged nodes.
func
(
self
*
Ethereum
)
TrustPeer
(
nodeURL
string
)
error
{
n
,
err
:=
discover
.
ParseNode
(
nodeURL
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"invalid node URL: %v"
,
err
)
}
self
.
net
.
Sugge
stPeer
(
n
)
self
.
net
.
Tru
stPeer
(
n
)
return
nil
}
...
...
p2p/server.go
View file @
de0549fa
...
...
@@ -18,8 +18,9 @@ import (
)
const
(
defaultDialTimeout
=
10
*
time
.
Second
refreshPeersInterval
=
30
*
time
.
Second
defaultDialTimeout
=
10
*
time
.
Second
refreshPeersInterval
=
30
*
time
.
Second
trustedPeerCheckInterval
=
15
*
time
.
Second
// This is the maximum number of inbound connection
// that are allowed to linger between 'accepted' and
...
...
@@ -59,6 +60,10 @@ type Server struct {
// with the rest of the network.
BootstrapNodes
[]
*
discover
.
Node
// Trusted nodes are used as privileged connections which are always accepted
// and also always maintained.
TrustedNodes
[]
*
discover
.
Node
// NodeDatabase is the path to the database containing the previously seen
// live nodes in the network.
NodeDatabase
string
...
...
@@ -99,13 +104,15 @@ type Server struct {
running
bool
peers
map
[
discover
.
NodeID
]
*
Peer
trusts
map
[
discover
.
NodeID
]
*
discover
.
Node
// Map of currently trusted remote nodes
trustDial
chan
*
discover
.
Node
// Dial request channel reserved for the trusted nodes
ntab
*
discover
.
Table
listener
net
.
Listener
quit
chan
struct
{}
loopWG
sync
.
WaitGroup
// {dial,listen,nat}Loop
peerWG
sync
.
WaitGroup
// active peer goroutines
peerConnect
chan
*
discover
.
Node
quit
chan
struct
{}
loopWG
sync
.
WaitGroup
// {dial,listen,nat}Loop
peerWG
sync
.
WaitGroup
// active peer goroutines
}
type
setupFunc
func
(
net
.
Conn
,
*
ecdsa
.
PrivateKey
,
*
protoHandshake
,
*
discover
.
Node
,
bool
)
(
*
conn
,
error
)
...
...
@@ -131,10 +138,9 @@ func (srv *Server) PeerCount() int {
return
n
}
// SuggestPeer creates a connection to the given Node if it
// is not already connected.
func
(
srv
*
Server
)
SuggestPeer
(
n
*
discover
.
Node
)
{
srv
.
peerConnect
<-
n
// TrustPeer inserts a node into the list of privileged nodes.
func
(
srv
*
Server
)
TrustPeer
(
node
*
discover
.
Node
)
{
srv
.
trustDial
<-
node
}
// Broadcast sends an RLP-encoded message to all connected peers.
...
...
@@ -195,7 +201,14 @@ func (srv *Server) Start() (err error) {
}
srv
.
quit
=
make
(
chan
struct
{})
srv
.
peers
=
make
(
map
[
discover
.
NodeID
]
*
Peer
)
srv
.
peerConnect
=
make
(
chan
*
discover
.
Node
)
// Create the current trust map, and the associated dialing channel
srv
.
trusts
=
make
(
map
[
discover
.
NodeID
]
*
discover
.
Node
)
for
_
,
node
:=
range
srv
.
TrustedNodes
{
srv
.
trusts
[
node
.
ID
]
=
node
}
srv
.
trustDial
=
make
(
chan
*
discover
.
Node
)
if
srv
.
setupFunc
==
nil
{
srv
.
setupFunc
=
setupConn
}
...
...
@@ -229,6 +242,8 @@ func (srv *Server) Start() (err error) {
if
srv
.
NoDial
&&
srv
.
ListenAddr
==
""
{
glog
.
V
(
logger
.
Warn
)
.
Infoln
(
"I will be kind-of useless, neither dialing nor listening."
)
}
// maintain the trusted peers
go
srv
.
trustLoop
()
srv
.
running
=
true
return
nil
...
...
@@ -323,6 +338,45 @@ func (srv *Server) listenLoop() {
}
}
// trustLoop is responsible for periodically checking that trusted connections
// are actually live, and requests dialing if not.
func
(
srv
*
Server
)
trustLoop
()
{
// Create a ticker for verifying trusted connections
tick
:=
time
.
Tick
(
trustedPeerCheckInterval
)
for
{
select
{
case
<-
srv
.
quit
:
// Termination requested, simple return
return
case
<-
tick
:
// Collect all the non-connected trusted nodes
needed
:=
[]
*
discover
.
Node
{}
srv
.
lock
.
RLock
()
for
id
,
node
:=
range
srv
.
trusts
{
if
_
,
ok
:=
srv
.
peers
[
id
];
!
ok
{
needed
=
append
(
needed
,
node
)
}
}
srv
.
lock
.
RUnlock
()
// Try to dial each of them (don't hang if server terminates)
for
_
,
node
:=
range
needed
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Dialing trusted peer %v"
,
node
)
select
{
case
srv
.
trustDial
<-
node
:
// Ok, dialing
case
<-
srv
.
quit
:
// Terminating, return
return
}
}
}
}
}
func
(
srv
*
Server
)
dialLoop
()
{
var
(
dialed
=
make
(
chan
*
discover
.
Node
)
...
...
@@ -373,7 +427,7 @@ func (srv *Server) dialLoop() {
// below MaxPeers.
refresh
.
Reset
(
refreshPeersInterval
)
}
case
dest
:=
<-
srv
.
peerConnect
:
case
dest
:=
<-
srv
.
trustDial
:
dial
(
dest
)
case
dests
:=
<-
findresults
:
for
_
,
dest
:=
range
dests
{
...
...
@@ -472,16 +526,26 @@ func (srv *Server) addPeer(id discover.NodeID, p *Peer) (bool, DiscReason) {
return
true
,
0
}
// checkPeer verifies whether a peer looks promising and should be allowed/kept
// in the pool, or if it's of no use.
func
(
srv
*
Server
)
checkPeer
(
id
discover
.
NodeID
)
(
bool
,
DiscReason
)
{
// First up, figure out if the peer is trusted
_
,
trusted
:=
srv
.
trusts
[
id
]
// Make sure the peer passes all required checks
switch
{
case
!
srv
.
running
:
return
false
,
DiscQuitting
case
len
(
srv
.
peers
)
>=
srv
.
MaxPeers
:
case
!
trusted
&&
len
(
srv
.
peers
)
>=
srv
.
MaxPeers
:
return
false
,
DiscTooManyPeers
case
srv
.
peers
[
id
]
!=
nil
:
return
false
,
DiscAlreadyConnected
case
id
==
srv
.
ntab
.
Self
()
.
ID
:
return
false
,
DiscSelf
default
:
return
true
,
0
}
...
...
p2p/server_test.go
View file @
de0549fa
...
...
@@ -102,7 +102,7 @@ func TestServerDial(t *testing.T) {
// tell the server to connect
tcpAddr
:=
listener
.
Addr
()
.
(
*
net
.
TCPAddr
)
srv
.
SuggestPeer
(
&
discover
.
Node
{
IP
:
tcpAddr
.
IP
,
TCPPort
:
tcpAddr
.
Port
})
srv
.
trustDial
<-&
discover
.
Node
{
IP
:
tcpAddr
.
IP
,
TCPPort
:
tcpAddr
.
Port
}
select
{
case
conn
:=
<-
accepted
:
...
...
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