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
00065853
Commit
00065853
authored
Feb 19, 2015
by
obscuren
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of github.com-obscure:ethereum/go-ethereum into develop
parents
fa4cbad3
639ac5c3
Changes
19
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
658 additions
and
662 deletions
+658
-662
main.go
cmd/ethereum/main.go
+1
-0
mist.js
cmd/mist/assets/ext/mist.js
+8
-6
main.qml
cmd/mist/assets/qml/main.qml
+7
-2
browser.qml
cmd/mist/assets/qml/views/browser.qml
+6
-4
catalog.qml
cmd/mist/assets/qml/views/catalog.qml
+7
-12
flags.go
cmd/mist/flags.go
+3
-0
gui.go
cmd/mist/gui.go
+2
-1
main.go
cmd/mist/main.go
+14
-13
cmd.go
cmd/utils/cmd.go
+1
-1
backend.go
eth/backend.go
+3
-3
types.go
logger/types.go
+285
-288
miner.go
miner/miner.go
+2
-2
handshake.go
p2p/handshake.go
+104
-33
handshake_test.go
p2p/handshake_test.go
+60
-3
message.go
p2p/message.go
+1
-1
peer.go
p2p/peer.go
+84
-180
peer_test.go
p2p/peer_test.go
+20
-85
server.go
p2p/server.go
+43
-23
server_test.go
p2p/server_test.go
+7
-5
No files found.
cmd/ethereum/main.go
View file @
00065853
...
...
@@ -67,6 +67,7 @@ func main() {
DataDir
:
Datadir
,
LogFile
:
LogFile
,
LogLevel
:
LogLevel
,
LogFormat
:
LogFormat
,
MaxPeers
:
MaxPeer
,
Port
:
OutboundPort
,
NAT
:
NAT
,
...
...
cmd/mist/assets/ext/mist.js
View file @
00065853
...
...
@@ -20,16 +20,18 @@
console
.
log
(
"loaded?"
);
document
.
onkeydown
=
function
(
evt
)
{
// This functions keeps track of keyboard inputs in order to allow copy, paste and other features
evt
=
evt
||
window
.
event
;
if
(
evt
.
ctrlKey
&&
evt
.
keyCode
==
67
)
{
window
.
document
.
execCommand
(
"copy"
);
console
.
log
(
"Ctrl-C"
);
}
else
if
(
evt
.
ctrlKey
&&
evt
.
keyCode
==
88
)
{
window
.
document
.
execCommand
(
"cut"
);
console
.
log
(
"Ctrl-X"
);
}
if
(
evt
.
ctrlKey
&&
evt
.
keyCode
==
86
)
{
console
.
log
(
"Ctrl-V"
);
}
if
(
evt
.
ctrlKey
&&
evt
.
keyCode
==
90
)
{
console
.
log
(
"Ctrl-Z"
);
}
else
if
(
evt
.
ctrlKey
&&
evt
.
keyCode
==
86
)
{
window
.
document
.
execCommand
(
"paste"
);
}
else
if
(
evt
.
ctrlKey
&&
evt
.
keyCode
==
90
)
{
window
.
document
.
execCommand
(
"undo"
);
}
else
if
(
evt
.
ctrlKey
&&
evt
.
shiftKey
&&
evt
.
keyCode
==
90
)
{
window
.
document
.
execCommand
(
"redo"
);
}
};
\ No newline at end of file
cmd/mist/assets/qml/main.qml
View file @
00065853
...
...
@@ -131,7 +131,11 @@ ApplicationWindow {
var
existingDomain
=
matches
&&
matches
[
1
];
if
(
requestedDomain
==
existingDomain
)
{
domainAlreadyOpen
=
true
;
if
(
mainSplit
.
views
[
i
].
view
.
url
!=
url
){
mainSplit
.
views
[
i
].
view
.
url
=
url
;
}
activeView
(
mainSplit
.
views
[
i
].
view
,
mainSplit
.
views
[
i
].
menuItem
);
}
}
...
...
@@ -928,7 +932,8 @@ ApplicationWindow {
model
:
peerModel
TableViewColumn
{
width
:
180
;
role
:
"addr"
;
title
:
"Remote Address"
}
TableViewColumn
{
width
:
280
;
role
:
"nodeID"
;
title
:
"Node ID"
}
TableViewColumn
{
width
:
180
;
role
:
"caps"
;
title
:
"Capabilities"
}
TableViewColumn
{
width
:
100
;
role
:
"name"
;
title
:
"Name"
}
TableViewColumn
{
width
:
40
;
role
:
"caps"
;
title
:
"Capabilities"
}
}
}
}
...
...
cmd/mist/assets/qml/views/browser.qml
View file @
00065853
...
...
@@ -3,7 +3,7 @@ import QtQuick.Controls 1.0;
import
QtQuick
.
Controls
.
Styles
1.0
import
QtQuick
.
Layouts
1.0
;
import
QtWebEngine
1.0
//
import QtWebEngine.experimental 1.0
import
QtWebEngine
.
experimental
1.0
import
QtQuick
.
Window
2.0
;
Rectangle
{
...
...
@@ -340,7 +340,7 @@ Rectangle {
WebEngineView
{
objectName
:
"webView"
id
:
webview
//
experimental.settings.javascriptCanAccessClipboard: true
experimental.settings.javascriptCanAccessClipboard
:
true
//experimental.settings.localContentCanAccessRemoteUrls: true
anchors
{
left
:
parent
.
left
...
...
@@ -399,6 +399,7 @@ Rectangle {
onLoadingChanged
:
{
if
(
loadRequest
.
status
==
WebEngineView
.
LoadSucceededStatus
)
{
webview
.
runJavaScript
(
"document.title"
,
function
(
pageTitle
)
{
menuItem
.
title
=
pageTitle
;
});
...
...
@@ -441,6 +442,7 @@ Rectangle {
webview
.
runJavaScript
(
eth
.
readFile
(
"bignumber.min.js"
));
webview
.
runJavaScript
(
eth
.
readFile
(
"ethereum.js/dist/ethereum.js"
));
webview
.
runJavaScript
(
eth
.
readFile
(
"mist.js"
));
var
cleanTitle
=
webview
.
url
.
toString
()
var
matches
=
cleanTitle
.
match
(
/^
[
a-z
]
*
\:\/\/([^\/
?#
]
+
)(?:[\/
?#
]
|$
)
/i
);
...
...
cmd/mist/assets/qml/views/catalog.qml
View file @
00065853
...
...
@@ -3,7 +3,7 @@ import QtQuick.Controls 1.0;
import
QtQuick
.
Controls
.
Styles
1.0
import
QtQuick
.
Layouts
1.0
;
import
QtWebEngine
1.0
//
import QtWebEngine.experimental 1.0
import
QtWebEngine
.
experimental
1.0
import
QtQuick
.
Window
2.0
;
...
...
@@ -21,8 +21,6 @@ Rectangle {
property
alias
windowTitle
:
webview
.
title
property
alias
webView
:
webview
property
var
cleanPath
:
false
property
var
open
:
function
(
url
)
{
if
(
!
window
.
cleanPath
)
{
...
...
@@ -66,9 +64,6 @@ Rectangle {
}
}
Component.onCompleted
:
{
}
Item
{
objectName
:
"root"
id
:
root
...
...
@@ -85,7 +80,7 @@ Rectangle {
property
var
domain
:
"ethereum-dapp-catalog.meteor.com"
url
:
protocol
+
domain
//
experimental.settings.javascriptCanAccessClipboard: true
experimental.settings.javascriptCanAccessClipboard
:
true
onJavaScriptConsoleMessage
:
{
...
...
@@ -112,11 +107,11 @@ Rectangle {
}
}
//
onLoadingChanged: {
//
if (loadRequest.status == WebEngineView.LoadSucceededStatus) {
//
webview.runJavaScript(eth.readFile("mist.js"));
//
}
//
}
onLoadingChanged
:
{
if
(
loadRequest
.
status
==
WebEngineView
.
LoadSucceededStatus
)
{
webview
.
runJavaScript
(
eth
.
readFile
(
"mist.js"
));
}
}
}
...
...
cmd/mist/flags.go
View file @
00065853
...
...
@@ -63,6 +63,7 @@ var (
DebugFile
string
LogLevel
int
VmType
int
MinerThreads
int
)
// flags specific to gui client
...
...
@@ -137,6 +138,8 @@ func Init() {
flag
.
StringVar
(
&
BootNodes
,
"bootnodes"
,
""
,
"space-separated node URLs for discovery bootstrap"
)
flag
.
IntVar
(
&
MaxPeer
,
"maxpeer"
,
30
,
"maximum desired peers"
)
flag
.
IntVar
(
&
MinerThreads
,
"minerthreads"
,
runtime
.
NumCPU
(),
"number of miner threads"
)
flag
.
Parse
()
var
err
error
...
...
cmd/mist/gui.go
View file @
00065853
...
...
@@ -453,7 +453,7 @@ NumGC: %d
))
}
type
qmlpeer
struct
{
Addr
,
NodeID
,
Caps
string
}
type
qmlpeer
struct
{
Addr
,
NodeID
,
Name
,
Caps
string
}
type
peersByID
[]
*
qmlpeer
...
...
@@ -468,6 +468,7 @@ func (gui *Gui) setPeerInfo() {
qpeers
[
i
]
=
&
qmlpeer
{
NodeID
:
p
.
ID
()
.
String
(),
Addr
:
p
.
RemoteAddr
()
.
String
(),
Name
:
p
.
Name
(),
Caps
:
fmt
.
Sprint
(
p
.
Caps
()),
}
}
...
...
cmd/mist/main.go
View file @
00065853
...
...
@@ -65,6 +65,7 @@ func run() error {
NodeKey
:
NodeKey
,
KeyRing
:
KeyRing
,
Dial
:
true
,
MinerThreads
:
MinerThreads
,
})
if
err
!=
nil
{
mainlogger
.
Fatalln
(
err
)
...
...
cmd/utils/cmd.go
View file @
00065853
...
...
@@ -225,7 +225,7 @@ func StartMining(ethereum *eth.Ethereum) bool {
go
func
()
{
clilogger
.
Infoln
(
"Start mining"
)
if
gminer
==
nil
{
gminer
=
miner
.
New
(
addr
,
ethereum
)
gminer
=
miner
.
New
(
addr
,
ethereum
,
4
)
}
gminer
.
Start
()
}()
...
...
eth/backend.go
View file @
00065853
...
...
@@ -53,6 +53,8 @@ type Config struct {
Shh
bool
Dial
bool
MinerThreads
int
KeyManager
*
crypto
.
KeyManager
}
...
...
@@ -153,7 +155,7 @@ func New(config *Config) (*Ethereum, error) {
eth
.
blockProcessor
=
core
.
NewBlockProcessor
(
db
,
eth
.
txPool
,
eth
.
chainManager
,
eth
.
EventMux
())
eth
.
chainManager
.
SetProcessor
(
eth
.
blockProcessor
)
eth
.
whisper
=
whisper
.
New
()
eth
.
miner
=
miner
.
New
(
keyManager
.
Address
(),
eth
)
eth
.
miner
=
miner
.
New
(
keyManager
.
Address
(),
eth
,
config
.
MinerThreads
)
hasBlock
:=
eth
.
chainManager
.
HasBlock
insertChain
:=
eth
.
chainManager
.
InsertChain
...
...
@@ -209,9 +211,7 @@ func (s *Ethereum) Coinbase() []byte { return nil } // TODO
func
(
s
*
Ethereum
)
Start
()
error
{
jsonlogger
.
LogJson
(
&
ethlogger
.
LogStarting
{
ClientString
:
s
.
net
.
Name
,
Coinbase
:
ethutil
.
Bytes2Hex
(
s
.
KeyManager
()
.
Address
()),
ProtocolVersion
:
ProtocolVersion
,
LogEvent
:
ethlogger
.
LogEvent
{
Guid
:
ethutil
.
Bytes2Hex
(
crypto
.
FromECDSAPub
(
&
s
.
net
.
PrivateKey
.
PublicKey
))},
})
err
:=
s
.
net
.
Start
()
...
...
logger/types.go
View file @
00065853
This diff is collapsed.
Click to expand it.
miner/miner.go
View file @
00065853
...
...
@@ -20,13 +20,13 @@ type Miner struct {
mining
bool
}
func
New
(
coinbase
[]
byte
,
eth
core
.
Backend
)
*
Miner
{
func
New
(
coinbase
[]
byte
,
eth
core
.
Backend
,
minerThreads
int
)
*
Miner
{
miner
:=
&
Miner
{
Coinbase
:
coinbase
,
worker
:
newWorker
(
coinbase
,
eth
),
}
for
i
:=
0
;
i
<
4
;
i
++
{
for
i
:=
0
;
i
<
minerThreads
;
i
++
{
miner
.
worker
.
register
(
NewCpuMiner
(
i
,
ezp
.
New
()))
}
...
...
p2p/
crypto
.go
→
p2p/
handshake
.go
View file @
00065853
package
p2p
import
(
// "binary"
"crypto/ecdsa"
"crypto/rand"
"errors"
"fmt"
"io"
"net"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/ecies"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
ethlogger
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/rlp"
)
var
clogger
=
ethlogger
.
NewLogger
(
"CRYPTOID"
)
const
(
sskLen
=
16
// ecies.MaxSharedKeyLength(pubKey) / 2
sigLen
=
65
// elliptic S256
...
...
@@ -30,26 +29,76 @@ const (
rHSLen
=
authRespLen
+
eciesBytes
// size of the final ECIES payload sent as receiver's handshake
)
type
hexkey
[]
byte
type
conn
struct
{
*
frameRW
*
protoHandshake
}
func
(
self
hexkey
)
String
()
string
{
return
fmt
.
Sprintf
(
"(%d) %x"
,
len
(
self
),
[]
byte
(
self
))
func
newConn
(
fd
net
.
Conn
,
hs
*
protoHandshake
)
*
conn
{
return
&
conn
{
newFrameRW
(
fd
,
msgWriteTimeout
),
hs
}
}
func
encHandshake
(
conn
io
.
ReadWriter
,
prv
*
ecdsa
.
PrivateKey
,
dial
*
discover
.
Node
)
(
remoteID
discover
.
NodeID
,
sessionToken
[]
byte
,
err
error
,
)
{
// encHandshake represents information about the remote end
// of a connection that is negotiated during the encryption handshake.
type
encHandshake
struct
{
ID
discover
.
NodeID
IngressMAC
[]
byte
EgressMAC
[]
byte
Token
[]
byte
}
// protoHandshake is the RLP structure of the protocol handshake.
type
protoHandshake
struct
{
Version
uint64
Name
string
Caps
[]
Cap
ListenPort
uint64
ID
discover
.
NodeID
}
// setupConn starts a protocol session on the given connection.
// It runs the encryption handshake and the protocol handshake.
// If dial is non-nil, the connection the local node is the initiator.
func
setupConn
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
dial
*
discover
.
Node
)
(
*
conn
,
error
)
{
if
dial
==
nil
{
var
remotePubkey
[]
byte
sessionToken
,
remotePubkey
,
err
=
inboundEncHandshake
(
conn
,
prv
,
nil
)
copy
(
remoteID
[
:
],
remotePubkey
)
return
setupInboundConn
(
fd
,
prv
,
our
)
}
else
{
remoteID
=
dial
.
ID
sessionToken
,
err
=
outboundEncHandshake
(
conn
,
prv
,
remoteID
[
:
],
nil
)
return
setupOutboundConn
(
fd
,
prv
,
our
,
dial
)
}
}
func
setupInboundConn
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
)
(
*
conn
,
error
)
{
// var remotePubkey []byte
// sessionToken, remotePubkey, err = inboundEncHandshake(fd, prv, nil)
// copy(remoteID[:], remotePubkey)
rw
:=
newFrameRW
(
fd
,
msgWriteTimeout
)
rhs
,
err
:=
readProtocolHandshake
(
rw
,
our
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
writeProtocolHandshake
(
rw
,
our
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"protocol write error: %v"
,
err
)
}
return
&
conn
{
rw
,
rhs
},
nil
}
func
setupOutboundConn
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
dial
*
discover
.
Node
)
(
*
conn
,
error
)
{
// remoteID = dial.ID
// sessionToken, err = outboundEncHandshake(fd, prv, remoteID[:], nil)
rw
:=
newFrameRW
(
fd
,
msgWriteTimeout
)
if
err
:=
writeProtocolHandshake
(
rw
,
our
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"protocol write error: %v"
,
err
)
}
return
remoteID
,
sessionToken
,
err
rhs
,
err
:=
readProtocolHandshake
(
rw
,
our
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"protocol handshake read error: %v"
,
err
)
}
if
rhs
.
ID
!=
dial
.
ID
{
return
nil
,
errors
.
New
(
"dialed node id mismatch"
)
}
return
&
conn
{
rw
,
rhs
},
nil
}
// outboundEncHandshake negotiates a session token on conn.
...
...
@@ -66,18 +115,9 @@ func outboundEncHandshake(conn io.ReadWriter, prvKey *ecdsa.PrivateKey, remotePu
if
err
!=
nil
{
return
nil
,
err
}
if
sessionToken
!=
nil
{
clogger
.
Debugf
(
"session-token: %v"
,
hexkey
(
sessionToken
))
}
clogger
.
Debugf
(
"initiator-nonce: %v"
,
hexkey
(
initNonce
))
clogger
.
Debugf
(
"initiator-random-private-key: %v"
,
hexkey
(
crypto
.
FromECDSA
(
randomPrivKey
)))
randomPublicKeyS
,
_
:=
exportPublicKey
(
&
randomPrivKey
.
PublicKey
)
clogger
.
Debugf
(
"initiator-random-public-key: %v"
,
hexkey
(
randomPublicKeyS
))
if
_
,
err
=
conn
.
Write
(
auth
);
err
!=
nil
{
return
nil
,
err
}
clogger
.
Debugf
(
"initiator handshake: %v"
,
hexkey
(
auth
))
response
:=
make
([]
byte
,
rHSLen
)
if
_
,
err
=
io
.
ReadFull
(
conn
,
response
);
err
!=
nil
{
...
...
@@ -88,9 +128,6 @@ func outboundEncHandshake(conn io.ReadWriter, prvKey *ecdsa.PrivateKey, remotePu
return
nil
,
err
}
clogger
.
Debugf
(
"receiver-nonce: %v"
,
hexkey
(
recNonce
))
remoteRandomPubKeyS
,
_
:=
exportPublicKey
(
remoteRandomPubKey
)
clogger
.
Debugf
(
"receiver-random-public-key: %v"
,
hexkey
(
remoteRandomPubKeyS
))
return
newSession
(
initNonce
,
recNonce
,
randomPrivKey
,
remoteRandomPubKey
)
}
...
...
@@ -221,12 +258,9 @@ func inboundEncHandshake(conn io.ReadWriter, prvKey *ecdsa.PrivateKey, sessionTo
if
err
!=
nil
{
return
nil
,
nil
,
err
}
clogger
.
Debugf
(
"receiver-nonce: %v"
,
hexkey
(
recNonce
))
clogger
.
Debugf
(
"receiver-random-priv-key: %v"
,
hexkey
(
crypto
.
FromECDSA
(
randomPrivKey
)))
if
_
,
err
=
conn
.
Write
(
response
);
err
!=
nil
{
return
nil
,
nil
,
err
}
clogger
.
Debugf
(
"receiver handshake:
\n
%v"
,
hexkey
(
response
))
token
,
err
=
newSession
(
initNonce
,
recNonce
,
randomPrivKey
,
remoteRandomPubKey
)
return
token
,
remotePubKey
,
err
}
...
...
@@ -361,3 +395,40 @@ func xor(one, other []byte) (xor []byte) {
}
return
xor
}
func
writeProtocolHandshake
(
w
MsgWriter
,
our
*
protoHandshake
)
error
{
return
EncodeMsg
(
w
,
handshakeMsg
,
our
.
Version
,
our
.
Name
,
our
.
Caps
,
our
.
ListenPort
,
our
.
ID
[
:
])
}
func
readProtocolHandshake
(
r
MsgReader
,
our
*
protoHandshake
)
(
*
protoHandshake
,
error
)
{
// read and handle remote handshake
msg
,
err
:=
r
.
ReadMsg
()
if
err
!=
nil
{
return
nil
,
err
}
if
msg
.
Code
==
discMsg
{
// disconnect before protocol handshake is valid according to the
// spec and we send it ourself if Server.addPeer fails.
var
reason
DiscReason
rlp
.
Decode
(
msg
.
Payload
,
&
reason
)
return
nil
,
discRequestedError
(
reason
)
}
if
msg
.
Code
!=
handshakeMsg
{
return
nil
,
fmt
.
Errorf
(
"expected handshake, got %x"
,
msg
.
Code
)
}
if
msg
.
Size
>
baseProtocolMaxMsgSize
{
return
nil
,
fmt
.
Errorf
(
"message too big (%d > %d)"
,
msg
.
Size
,
baseProtocolMaxMsgSize
)
}
var
hs
protoHandshake
if
err
:=
msg
.
Decode
(
&
hs
);
err
!=
nil
{
return
nil
,
err
}
// validate handshake info
if
hs
.
Version
!=
our
.
Version
{
return
nil
,
newPeerError
(
errP2PVersionMismatch
,
"required version %d, received %d
\n
"
,
baseProtocolVersion
,
hs
.
Version
)
}
if
(
hs
.
ID
==
discover
.
NodeID
{})
{
return
nil
,
newPeerError
(
errPubkeyInvalid
,
"missing"
)
}
return
&
hs
,
nil
}
p2p/
crypto
_test.go
→
p2p/
handshake
_test.go
View file @
00065853
...
...
@@ -5,10 +5,12 @@ import (
"crypto/ecdsa"
"crypto/rand"
"net"
"reflect"
"testing"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/ecies"
"github.com/ethereum/go-ethereum/p2p/discover"
)
func
TestPublicKeyEncoding
(
t
*
testing
.
T
)
{
...
...
@@ -91,14 +93,14 @@ func testCryptoHandshake(prv0, prv1 *ecdsa.PrivateKey, sessionToken []byte, t *t
if
err
!=
nil
{
t
.
Errorf
(
"%v"
,
err
)
}
t
.
Logf
(
"-> %v"
,
hexkey
(
auth
))
//
t.Logf("-> %v", hexkey(auth))
// receiver reads auth and responds with response
response
,
remoteRecNonce
,
remoteInitNonce
,
_
,
remoteRandomPrivKey
,
remoteInitRandomPubKey
,
err
:=
authResp
(
auth
,
sessionToken
,
prv1
)
if
err
!=
nil
{
t
.
Errorf
(
"%v"
,
err
)
}
t
.
Logf
(
"<- %v
\n
"
,
hexkey
(
response
))
//
t.Logf("<- %v\n", hexkey(response))
// initiator reads receiver's response and the key exchange completes
recNonce
,
remoteRandomPubKey
,
_
,
err
:=
completeHandshake
(
response
,
prv0
)
...
...
@@ -132,7 +134,7 @@ func testCryptoHandshake(prv0, prv1 *ecdsa.PrivateKey, sessionToken []byte, t *t
}
}
func
TestHandshake
(
t
*
testing
.
T
)
{
func
Test
Enc
Handshake
(
t
*
testing
.
T
)
{
defer
testlog
(
t
)
.
detach
()
prv0
,
_
:=
crypto
.
GenerateKey
()
...
...
@@ -165,3 +167,58 @@ func TestHandshake(t *testing.T) {
t
.
Error
(
"session token mismatch"
)
}
}
func
TestSetupConn
(
t
*
testing
.
T
)
{
prv0
,
_
:=
crypto
.
GenerateKey
()
prv1
,
_
:=
crypto
.
GenerateKey
()
node0
:=
&
discover
.
Node
{
ID
:
discover
.
PubkeyID
(
&
prv0
.
PublicKey
),
IP
:
net
.
IP
{
1
,
2
,
3
,
4
},
TCPPort
:
33
,
}
node1
:=
&
discover
.
Node
{
ID
:
discover
.
PubkeyID
(
&
prv1
.
PublicKey
),
IP
:
net
.
IP
{
5
,
6
,
7
,
8
},
TCPPort
:
44
,
}
hs0
:=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
ID
:
node0
.
ID
,
Caps
:
[]
Cap
{{
"a"
,
0
},
{
"b"
,
2
}},
}
hs1
:=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
ID
:
node1
.
ID
,
Caps
:
[]
Cap
{{
"c"
,
1
},
{
"d"
,
3
}},
}
fd0
,
fd1
:=
net
.
Pipe
()
done
:=
make
(
chan
struct
{})
go
func
()
{
defer
close
(
done
)
conn0
,
err
:=
setupConn
(
fd0
,
prv0
,
hs0
,
node1
)
if
err
!=
nil
{
t
.
Errorf
(
"outbound side error: %v"
,
err
)
return
}
if
conn0
.
ID
!=
node1
.
ID
{
t
.
Errorf
(
"outbound conn id mismatch: got %v, want %v"
,
conn0
.
ID
,
node1
.
ID
)
}
if
!
reflect
.
DeepEqual
(
conn0
.
Caps
,
hs1
.
Caps
)
{
t
.
Errorf
(
"outbound caps mismatch: got %v, want %v"
,
conn0
.
Caps
,
hs1
.
Caps
)
}
}()
conn1
,
err
:=
setupConn
(
fd1
,
prv1
,
hs1
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"inbound side error: %v"
,
err
)
}
if
conn1
.
ID
!=
node0
.
ID
{
t
.
Errorf
(
"inbound conn id mismatch: got %v, want %v"
,
conn1
.
ID
,
node0
.
ID
)
}
if
!
reflect
.
DeepEqual
(
conn1
.
Caps
,
hs0
.
Caps
)
{
t
.
Errorf
(
"inbound caps mismatch: got %v, want %v"
,
conn1
.
Caps
,
hs0
.
Caps
)
}
<-
done
}
p2p/message.go
View file @
00065853
...
...
@@ -197,7 +197,7 @@ func (rw *frameRW) ReadMsg() (msg Msg, err error) {
return
msg
,
err
}
if
!
bytes
.
HasPrefix
(
start
,
magicToken
)
{
return
msg
,
fmt
.
Errorf
(
"bad magic token %x"
,
start
[
:
4
]
,
magicToken
)
return
msg
,
fmt
.
Errorf
(
"bad magic token %x"
,
start
[
:
4
])
}
size
:=
binary
.
BigEndian
.
Uint32
(
start
[
4
:
])
...
...
p2p/peer.go
View file @
00065853
This diff is collapsed.
Click to expand it.
p2p/peer_test.go
View file @
00065853
...
...
@@ -6,11 +6,9 @@ import (
"io/ioutil"
"net"
"reflect"
"sort"
"testing"
"time"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/rlp"
)
...
...
@@ -23,6 +21,7 @@ var discard = Protocol{
if
err
!=
nil
{
return
err
}
fmt
.
Printf
(
"discarding %d
\n
"
,
msg
.
Code
)
if
err
=
msg
.
Discard
();
err
!=
nil
{
return
err
}
...
...
@@ -30,13 +29,20 @@ var discard = Protocol{
},
}
func
testPeer
(
noHandshake
bool
,
protos
[]
Protocol
)
(
*
frameRW
,
*
Peer
,
<-
chan
DiscReason
)
{
conn1
,
conn2
:=
net
.
Pipe
()
peer
:=
newPeer
(
conn1
,
protos
,
"name"
,
&
discover
.
NodeID
{},
&
discover
.
NodeID
{})
peer
.
noHandshake
=
noHandshake
func
testPeer
(
protos
[]
Protocol
)
(
*
conn
,
*
Peer
,
<-
chan
DiscReason
)
{
fd1
,
fd2
:=
net
.
Pipe
()
hs1
:=
&
protoHandshake
{
ID
:
randomID
(),
Version
:
baseProtocolVersion
}
hs2
:=
&
protoHandshake
{
ID
:
randomID
(),
Version
:
baseProtocolVersion
}
for
_
,
p
:=
range
protos
{
hs1
.
Caps
=
append
(
hs1
.
Caps
,
p
.
cap
())
hs2
.
Caps
=
append
(
hs2
.
Caps
,
p
.
cap
())
}
peer
:=
newPeer
(
newConn
(
fd1
,
hs1
),
protos
)
errc
:=
make
(
chan
DiscReason
,
1
)
go
func
()
{
errc
<-
peer
.
run
()
}()
return
newFrameRW
(
conn2
,
msgWriteTimeout
),
peer
,
errc
return
newConn
(
fd2
,
hs2
),
peer
,
errc
}
func
TestPeerProtoReadMsg
(
t
*
testing
.
T
)
{
...
...
@@ -61,9 +67,8 @@ func TestPeerProtoReadMsg(t *testing.T) {
},
}
rw
,
peer
,
errc
:=
testPeer
(
true
,
[]
Protocol
{
proto
})
rw
,
_
,
errc
:=
testPeer
(
[]
Protocol
{
proto
})
defer
rw
.
Close
()
peer
.
startSubprotocols
([]
Cap
{
proto
.
cap
()})
EncodeMsg
(
rw
,
baseProtocolLength
+
2
,
1
)
EncodeMsg
(
rw
,
baseProtocolLength
+
3
,
2
)
...
...
@@ -100,9 +105,8 @@ func TestPeerProtoReadLargeMsg(t *testing.T) {
},
}
rw
,
peer
,
errc
:=
testPeer
(
true
,
[]
Protocol
{
proto
})
rw
,
_
,
errc
:=
testPeer
(
[]
Protocol
{
proto
})
defer
rw
.
Close
()
peer
.
startSubprotocols
([]
Cap
{
proto
.
cap
()})
EncodeMsg
(
rw
,
18
,
make
([]
byte
,
msgsize
))
select
{
...
...
@@ -130,9 +134,8 @@ func TestPeerProtoEncodeMsg(t *testing.T) {
return
nil
},
}
rw
,
peer
,
_
:=
testPeer
(
true
,
[]
Protocol
{
proto
})
rw
,
_
,
_
:=
testPeer
(
[]
Protocol
{
proto
})
defer
rw
.
Close
()
peer
.
startSubprotocols
([]
Cap
{
proto
.
cap
()})
if
err
:=
expectMsg
(
rw
,
17
,
[]
string
{
"foo"
,
"bar"
});
err
!=
nil
{
t
.
Error
(
err
)
...
...
@@ -142,9 +145,8 @@ func TestPeerProtoEncodeMsg(t *testing.T) {
func
TestPeerWriteForBroadcast
(
t
*
testing
.
T
)
{
defer
testlog
(
t
)
.
detach
()
rw
,
peer
,
peerErr
:=
testPeer
(
true
,
[]
Protocol
{
discard
})
rw
,
peer
,
peerErr
:=
testPeer
([]
Protocol
{
discard
})
defer
rw
.
Close
()
peer
.
startSubprotocols
([]
Cap
{
discard
.
cap
()})
// test write errors
if
err
:=
peer
.
writeProtoMsg
(
"b"
,
NewMsg
(
3
));
err
==
nil
{
...
...
@@ -160,7 +162,7 @@ func TestPeerWriteForBroadcast(t *testing.T) {
read
:=
make
(
chan
struct
{})
go
func
()
{
if
err
:=
expectMsg
(
rw
,
16
,
nil
);
err
!=
nil
{
t
.
Error
()
t
.
Error
(
err
)
}
close
(
read
)
}()
...
...
@@ -179,7 +181,7 @@ func TestPeerWriteForBroadcast(t *testing.T) {
func
TestPeerPing
(
t
*
testing
.
T
)
{
defer
testlog
(
t
)
.
detach
()
rw
,
_
,
_
:=
testPeer
(
true
,
nil
)
rw
,
_
,
_
:=
testPeer
(
nil
)
defer
rw
.
Close
()
if
err
:=
EncodeMsg
(
rw
,
pingMsg
);
err
!=
nil
{
t
.
Fatal
(
err
)
...
...
@@ -192,7 +194,7 @@ func TestPeerPing(t *testing.T) {
func
TestPeerDisconnect
(
t
*
testing
.
T
)
{
defer
testlog
(
t
)
.
detach
()
rw
,
_
,
disc
:=
testPeer
(
true
,
nil
)
rw
,
_
,
disc
:=
testPeer
(
nil
)
defer
rw
.
Close
()
if
err
:=
EncodeMsg
(
rw
,
discMsg
,
DiscQuitting
);
err
!=
nil
{
t
.
Fatal
(
err
)
...
...
@@ -206,73 +208,6 @@ func TestPeerDisconnect(t *testing.T) {
}
}
func
TestPeerHandshake
(
t
*
testing
.
T
)
{
defer
testlog
(
t
)
.
detach
()
// remote has two matching protocols: a and c
remote
:=
NewPeer
(
randomID
(),
""
,
[]
Cap
{{
"a"
,
1
},
{
"b"
,
999
},
{
"c"
,
3
}})
remoteID
:=
randomID
()
remote
.
ourID
=
&
remoteID
remote
.
ourName
=
"remote peer"
start
:=
make
(
chan
string
)
stop
:=
make
(
chan
struct
{})
run
:=
func
(
p
*
Peer
,
rw
MsgReadWriter
)
error
{
name
:=
rw
.
(
*
proto
)
.
name
if
name
!=
"a"
&&
name
!=
"c"
{
t
.
Errorf
(
"protocol %q should not be started"
,
name
)
}
else
{
start
<-
name
}
<-
stop
return
nil
}
protocols
:=
[]
Protocol
{
{
Name
:
"a"
,
Version
:
1
,
Length
:
1
,
Run
:
run
},
{
Name
:
"b"
,
Version
:
2
,
Length
:
1
,
Run
:
run
},
{
Name
:
"c"
,
Version
:
3
,
Length
:
1
,
Run
:
run
},
{
Name
:
"d"
,
Version
:
4
,
Length
:
1
,
Run
:
run
},
}
rw
,
p
,
disc
:=
testPeer
(
false
,
protocols
)
p
.
remoteID
=
remote
.
ourID
defer
rw
.
Close
()
// run the handshake
remoteProtocols
:=
[]
Protocol
{
protocols
[
0
],
protocols
[
2
]}
if
err
:=
writeProtocolHandshake
(
rw
,
"remote peer"
,
remoteID
,
remoteProtocols
);
err
!=
nil
{
t
.
Fatalf
(
"handshake write error: %v"
,
err
)
}
if
err
:=
readProtocolHandshake
(
remote
,
rw
);
err
!=
nil
{
t
.
Fatalf
(
"handshake read error: %v"
,
err
)
}
// check that all protocols have been started
var
started
[]
string
for
i
:=
0
;
i
<
2
;
i
++
{
select
{
case
name
:=
<-
start
:
started
=
append
(
started
,
name
)
case
<-
time
.
After
(
100
*
time
.
Millisecond
)
:
}
}
sort
.
Strings
(
started
)
if
!
reflect
.
DeepEqual
(
started
,
[]
string
{
"a"
,
"c"
})
{
t
.
Errorf
(
"wrong protocols started: %v"
,
started
)
}
// check that metadata has been set
if
p
.
ID
()
!=
remoteID
{
t
.
Errorf
(
"peer has wrong node ID: got %v, want %v"
,
p
.
ID
(),
remoteID
)
}
if
p
.
Name
()
!=
remote
.
ourName
{
t
.
Errorf
(
"peer has wrong node name: got %q, want %q"
,
p
.
Name
(),
remote
.
ourName
)
}
close
(
stop
)
expectMsg
(
rw
,
discMsg
,
nil
)
t
.
Logf
(
"disc reason: %v"
,
<-
disc
)
}
func
TestNewPeer
(
t
*
testing
.
T
)
{
name
:=
"nodename"
caps
:=
[]
Cap
{{
"foo"
,
2
},
{
"bar"
,
3
}}
...
...
p2p/server.go
View file @
00065853
...
...
@@ -5,7 +5,6 @@ import (
"crypto/ecdsa"
"errors"
"fmt"
"io"
"net"
"runtime"
"sync"
...
...
@@ -23,6 +22,7 @@ const (
)
var
srvlog
=
logger
.
NewLogger
(
"P2P Server"
)
var
srvjslog
=
logger
.
NewJsonLogger
()
// MakeName creates a node name that follows the ethereum convention
// for such names. It adds the operation system name and Go runtime version
...
...
@@ -83,9 +83,11 @@ type Server struct {
// Hooks for testing. These are useful because we can inhibit
// the whole protocol stack.
handshake
Func
setup
Func
newPeerHook
ourHandshake
*
protoHandshake
lock
sync
.
RWMutex
running
bool
listener
net
.
Listener
...
...
@@ -99,7 +101,7 @@ type Server struct {
peerConnect
chan
*
discover
.
Node
}
type
handshakeFunc
func
(
io
.
ReadWriter
,
*
ecdsa
.
PrivateKey
,
*
discover
.
Node
)
(
discover
.
NodeID
,
[]
byte
,
error
)
type
setupFunc
func
(
net
.
Conn
,
*
ecdsa
.
PrivateKey
,
*
protoHandshake
,
*
discover
.
Node
)
(
*
conn
,
error
)
type
newPeerHook
func
(
*
Peer
)
// Peers returns all connected peers.
...
...
@@ -159,7 +161,7 @@ func (srv *Server) Start() (err error) {
}
srvlog
.
Infoln
(
"Starting Server"
)
//
initialize all the
fields
//
static
fields
if
srv
.
PrivateKey
==
nil
{
return
fmt
.
Errorf
(
"Server.PrivateKey must be set to a non-nil key"
)
}
...
...
@@ -169,25 +171,32 @@ func (srv *Server) Start() (err error) {
srv
.
quit
=
make
(
chan
struct
{})
srv
.
peers
=
make
(
map
[
discover
.
NodeID
]
*
Peer
)
srv
.
peerConnect
=
make
(
chan
*
discover
.
Node
)
if
srv
.
handshakeFunc
==
nil
{
srv
.
handshakeFunc
=
encHandshake
if
srv
.
setupFunc
==
nil
{
srv
.
setupFunc
=
setupConn
}
if
srv
.
Blacklist
==
nil
{
srv
.
Blacklist
=
NewBlacklist
()
}
if
srv
.
ListenAddr
!=
""
{
if
err
:=
srv
.
startListening
();
err
!=
nil
{
// node table
ntab
,
err
:=
discover
.
ListenUDP
(
srv
.
PrivateKey
,
srv
.
ListenAddr
,
srv
.
NAT
)
if
err
!=
nil
{
return
err
}
srv
.
ntab
=
ntab
// handshake
srv
.
ourHandshake
=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
Name
:
srv
.
Name
,
ID
:
ntab
.
Self
()}
for
_
,
p
:=
range
srv
.
Protocols
{
srv
.
ourHandshake
.
Caps
=
append
(
srv
.
ourHandshake
.
Caps
,
p
.
cap
())
}
//
dial stuff
dt
,
err
:=
discover
.
ListenUDP
(
srv
.
PrivateKey
,
srv
.
ListenAddr
,
srv
.
NAT
)
if
err
!=
nil
{
//
listen/dial
if
srv
.
ListenAddr
!=
""
{
if
err
:=
srv
.
startListening
();
err
!=
nil
{
return
err
}
srv
.
ntab
=
dt
}
if
srv
.
Dialer
==
nil
{
srv
.
Dialer
=
&
net
.
Dialer
{
Timeout
:
defaultDialTimeout
}
}
...
...
@@ -347,30 +356,41 @@ func (srv *Server) findPeers() {
}
}
func
(
srv
*
Server
)
startPeer
(
conn
net
.
Conn
,
dest
*
discover
.
Node
)
{
func
(
srv
*
Server
)
startPeer
(
fd
net
.
Conn
,
dest
*
discover
.
Node
)
{
// TODO: handle/store session token
conn
.
SetDeadline
(
time
.
Now
()
.
Add
(
handshakeTimeout
))
remoteID
,
_
,
err
:=
srv
.
handshakeFunc
(
conn
,
srv
.
PrivateKey
,
dest
)
fd
.
SetDeadline
(
time
.
Now
()
.
Add
(
handshakeTimeout
))
conn
,
err
:=
srv
.
setupFunc
(
fd
,
srv
.
PrivateKey
,
srv
.
ourHandshake
,
dest
)
if
err
!=
nil
{
conn
.
Close
()
srvlog
.
Debugf
(
"
Encryption Handshake with %v failed: %v"
,
conn
.
RemoteAddr
(),
err
)
fd
.
Close
()
srvlog
.
Debugf
(
"
Handshake with %v failed: %v"
,
fd
.
RemoteAddr
(),
err
)
return
}
ourID
:=
srv
.
ntab
.
Self
()
p
:=
newPeer
(
conn
,
srv
.
Protocols
,
srv
.
Name
,
&
ourID
,
&
remoteID
)
if
ok
,
reason
:=
srv
.
addPeer
(
remoteID
,
p
);
!
ok
{
p
:=
newPeer
(
conn
,
srv
.
Protocols
)
if
ok
,
reason
:=
srv
.
addPeer
(
conn
.
ID
,
p
);
!
ok
{
srvlog
.
DebugDetailf
(
"Not adding %v (%v)
\n
"
,
p
,
reason
)
p
.
politeDisconnect
(
reason
)
return
}
srvlog
.
Debugf
(
"Added %v
\n
"
,
p
)
srvjslog
.
LogJson
(
&
logger
.
P2PConnected
{
RemoteId
:
fmt
.
Sprintf
(
"%x"
,
conn
.
ID
[
:
]),
RemoteAddress
:
conn
.
RemoteAddr
()
.
String
(),
RemoteVersionString
:
conn
.
Name
,
NumConnections
:
srv
.
PeerCount
(),
})
if
srv
.
newPeerHook
!=
nil
{
srv
.
newPeerHook
(
p
)
}
discreason
:=
p
.
run
()
srv
.
removePeer
(
p
)
srvlog
.
Debugf
(
"Removed %v (%v)
\n
"
,
p
,
discreason
)
srvjslog
.
LogJson
(
&
logger
.
P2PDisconnected
{
RemoteId
:
fmt
.
Sprintf
(
"%x"
,
conn
.
ID
[
:
]),
NumConnections
:
srv
.
PeerCount
(),
})
}
func
(
srv
*
Server
)
addPeer
(
id
discover
.
NodeID
,
p
*
Peer
)
(
bool
,
DiscReason
)
{
...
...
@@ -394,7 +414,7 @@ func (srv *Server) addPeer(id discover.NodeID, p *Peer) (bool, DiscReason) {
func
(
srv
*
Server
)
removePeer
(
p
*
Peer
)
{
srv
.
lock
.
Lock
()
delete
(
srv
.
peers
,
*
p
.
remoteID
)
delete
(
srv
.
peers
,
p
.
ID
()
)
srv
.
lock
.
Unlock
()
srv
.
peerWG
.
Done
()
}
...
...
p2p/server_test.go
View file @
00065853
...
...
@@ -21,8 +21,12 @@ func startTestServer(t *testing.T, pf newPeerHook) *Server {
ListenAddr
:
"127.0.0.1:0"
,
PrivateKey
:
newkey
(),
newPeerHook
:
pf
,
handshakeFunc
:
func
(
io
.
ReadWriter
,
*
ecdsa
.
PrivateKey
,
*
discover
.
Node
)
(
id
discover
.
NodeID
,
st
[]
byte
,
err
error
)
{
return
randomID
(),
nil
,
err
setupFunc
:
func
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
dial
*
discover
.
Node
)
(
*
conn
,
error
)
{
id
:=
randomID
()
return
&
conn
{
frameRW
:
newFrameRW
(
fd
,
msgWriteTimeout
),
protoHandshake
:
&
protoHandshake
{
ID
:
id
,
Version
:
baseProtocolVersion
},
},
nil
},
}
if
err
:=
server
.
Start
();
err
!=
nil
{
...
...
@@ -116,9 +120,7 @@ func TestServerBroadcast(t *testing.T) {
var
connected
sync
.
WaitGroup
srv
:=
startTestServer
(
t
,
func
(
p
*
Peer
)
{
p
.
protocols
=
[]
Protocol
{
discard
}
p
.
startSubprotocols
([]
Cap
{
discard
.
cap
()})
p
.
noHandshake
=
true
p
.
running
=
matchProtocols
([]
Protocol
{
discard
},
[]
Cap
{
discard
.
cap
()},
p
.
rw
)
connected
.
Done
()
})
defer
srv
.
Stop
()
...
...
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