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
70867904
Commit
70867904
authored
May 27, 2015
by
obscuren
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release/0.9.25'
parents
ceea1a70
2c532a72
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
361 additions
and
242 deletions
+361
-242
admin.go
cmd/geth/admin.go
+52
-18
js.go
cmd/geth/js.go
+1
-1
js_test.go
cmd/geth/js_test.go
+3
-1
main.go
cmd/geth/main.go
+8
-7
flags.go
cmd/utils/flags.go
+5
-1
solidity.go
common/compiler/solidity.go
+2
-0
block_processor.go
core/block_processor.go
+5
-2
chain_manager.go
core/chain_manager.go
+1
-1
transaction_pool.go
core/transaction_pool.go
+5
-0
transaction_pool_test.go
core/transaction_pool_test.go
+14
-0
backend.go
eth/backend.go
+5
-7
downloader.go
eth/downloader/downloader.go
+1
-1
sync.go
eth/sync.go
+0
-1
jsre.go
jsre/jsre.go
+86
-149
jsre_test.go
jsre/jsre_test.go
+6
-6
database.go
p2p/discover/database.go
+14
-3
database_test.go
p2p/discover/database_test.go
+11
-0
table.go
p2p/discover/table.go
+101
-30
server.go
p2p/server.go
+38
-11
jeth.go
rpc/jeth.go
+3
-3
No files found.
cmd/geth/admin.go
View file @
70867904
...
@@ -88,6 +88,7 @@ func (js *jsre) adminBindings() {
...
@@ -88,6 +88,7 @@ func (js *jsre) adminBindings() {
debug
.
Set
(
"getBlockRlp"
,
js
.
getBlockRlp
)
debug
.
Set
(
"getBlockRlp"
,
js
.
getBlockRlp
)
debug
.
Set
(
"setHead"
,
js
.
setHead
)
debug
.
Set
(
"setHead"
,
js
.
setHead
)
debug
.
Set
(
"processBlock"
,
js
.
debugBlock
)
debug
.
Set
(
"processBlock"
,
js
.
debugBlock
)
debug
.
Set
(
"seedhash"
,
js
.
seedHash
)
// undocumented temporary
// undocumented temporary
debug
.
Set
(
"waitForBlocks"
,
js
.
waitForBlocks
)
debug
.
Set
(
"waitForBlocks"
,
js
.
waitForBlocks
)
}
}
...
@@ -118,6 +119,27 @@ func (js *jsre) getBlock(call otto.FunctionCall) (*types.Block, error) {
...
@@ -118,6 +119,27 @@ func (js *jsre) getBlock(call otto.FunctionCall) (*types.Block, error) {
return
block
,
nil
return
block
,
nil
}
}
func
(
js
*
jsre
)
seedHash
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
>
0
{
if
call
.
Argument
(
0
)
.
IsNumber
()
{
num
,
_
:=
call
.
Argument
(
0
)
.
ToInteger
()
hash
,
err
:=
ethash
.
GetSeedHash
(
uint64
(
num
))
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
v
,
_
:=
call
.
Otto
.
ToValue
(
fmt
.
Sprintf
(
"0x%x"
,
hash
))
return
v
}
else
{
fmt
.
Println
(
"arg not a number"
)
}
}
else
{
fmt
.
Println
(
"requires number argument"
)
}
return
otto
.
UndefinedValue
()
}
func
(
js
*
jsre
)
pendingTransactions
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
pendingTransactions
(
call
otto
.
FunctionCall
)
otto
.
Value
{
txs
:=
js
.
ethereum
.
TxPool
()
.
GetTransactions
()
txs
:=
js
.
ethereum
.
TxPool
()
.
GetTransactions
()
...
@@ -144,7 +166,8 @@ func (js *jsre) pendingTransactions(call otto.FunctionCall) otto.Value {
...
@@ -144,7 +166,8 @@ func (js *jsre) pendingTransactions(call otto.FunctionCall) otto.Value {
}
}
}
}
return
js
.
re
.
ToVal
(
ltxs
)
v
,
_
:=
call
.
Otto
.
ToValue
(
ltxs
)
return
v
}
}
func
(
js
*
jsre
)
resend
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
resend
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
@@ -175,7 +198,8 @@ func (js *jsre) resend(call otto.FunctionCall) otto.Value {
...
@@ -175,7 +198,8 @@ func (js *jsre) resend(call otto.FunctionCall) otto.Value {
}
}
js
.
ethereum
.
TxPool
()
.
RemoveTransactions
(
types
.
Transactions
{
tx
.
tx
})
js
.
ethereum
.
TxPool
()
.
RemoveTransactions
(
types
.
Transactions
{
tx
.
tx
})
return
js
.
re
.
ToVal
(
ret
)
v
,
_
:=
call
.
Otto
.
ToValue
(
ret
)
return
v
}
}
fmt
.
Println
(
"first argument must be a transaction"
)
fmt
.
Println
(
"first argument must be a transaction"
)
...
@@ -198,12 +222,13 @@ func (js *jsre) sign(call otto.FunctionCall) otto.Value {
...
@@ -198,12 +222,13 @@ func (js *jsre) sign(call otto.FunctionCall) otto.Value {
fmt
.
Println
(
err
)
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
v
,
err
:=
js
.
xeth
.
Sign
(
signer
,
data
,
false
)
signed
,
err
:=
js
.
xeth
.
Sign
(
signer
,
data
,
false
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
err
)
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
return
js
.
re
.
ToVal
(
v
)
v
,
_
:=
call
.
Otto
.
ToValue
(
signed
)
return
v
}
}
func
(
js
*
jsre
)
debugBlock
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
debugBlock
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
@@ -217,10 +242,11 @@ func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value {
...
@@ -217,10 +242,11 @@ func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value {
vm
.
Debug
=
true
vm
.
Debug
=
true
_
,
err
=
js
.
ethereum
.
BlockProcessor
()
.
RetryProcess
(
block
)
_
,
err
=
js
.
ethereum
.
BlockProcessor
()
.
RetryProcess
(
block
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Info
ln
(
err
)
fmt
.
Print
ln
(
err
)
}
}
vm
.
Debug
=
old
vm
.
Debug
=
old
fmt
.
Println
(
"ok"
)
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
...
@@ -237,8 +263,8 @@ func (js *jsre) setHead(call otto.FunctionCall) otto.Value {
...
@@ -237,8 +263,8 @@ func (js *jsre) setHead(call otto.FunctionCall) otto.Value {
func
(
js
*
jsre
)
downloadProgress
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
downloadProgress
(
call
otto
.
FunctionCall
)
otto
.
Value
{
current
,
max
:=
js
.
ethereum
.
Downloader
()
.
Stats
()
current
,
max
:=
js
.
ethereum
.
Downloader
()
.
Stats
()
v
,
_
:=
call
.
Otto
.
ToValue
(
fmt
.
Sprintf
(
"%d/%d"
,
current
,
max
))
return
js
.
re
.
ToVal
(
fmt
.
Sprintf
(
"%d/%d"
,
current
,
max
))
return
v
}
}
func
(
js
*
jsre
)
getBlockRlp
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
getBlockRlp
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
@@ -248,7 +274,8 @@ func (js *jsre) getBlockRlp(call otto.FunctionCall) otto.Value {
...
@@ -248,7 +274,8 @@ func (js *jsre) getBlockRlp(call otto.FunctionCall) otto.Value {
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
encoded
,
_
:=
rlp
.
EncodeToBytes
(
block
)
encoded
,
_
:=
rlp
.
EncodeToBytes
(
block
)
return
js
.
re
.
ToVal
(
fmt
.
Sprintf
(
"%x"
,
encoded
))
v
,
_
:=
call
.
Otto
.
ToValue
(
fmt
.
Sprintf
(
"%x"
,
encoded
))
return
v
}
}
func
(
js
*
jsre
)
setExtra
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
setExtra
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
@@ -278,8 +305,9 @@ func (js *jsre) setGasPrice(call otto.FunctionCall) otto.Value {
...
@@ -278,8 +305,9 @@ func (js *jsre) setGasPrice(call otto.FunctionCall) otto.Value {
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
func
(
js
*
jsre
)
hashrate
(
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
hashrate
(
call
otto
.
FunctionCall
)
otto
.
Value
{
return
js
.
re
.
ToVal
(
js
.
ethereum
.
Miner
()
.
HashRate
())
v
,
_
:=
call
.
Otto
.
ToValue
(
js
.
ethereum
.
Miner
()
.
HashRate
())
return
v
}
}
func
(
js
*
jsre
)
makeDAG
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
makeDAG
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
@@ -495,15 +523,18 @@ func (js *jsre) newAccount(call otto.FunctionCall) otto.Value {
...
@@ -495,15 +523,18 @@ func (js *jsre) newAccount(call otto.FunctionCall) otto.Value {
fmt
.
Printf
(
"Could not create the account: %v"
,
err
)
fmt
.
Printf
(
"Could not create the account: %v"
,
err
)
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
return
js
.
re
.
ToVal
(
acct
.
Address
.
Hex
())
v
,
_
:=
call
.
Otto
.
ToValue
(
acct
.
Address
.
Hex
())
return
v
}
}
func
(
js
*
jsre
)
nodeInfo
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
nodeInfo
(
call
otto
.
FunctionCall
)
otto
.
Value
{
return
js
.
re
.
ToVal
(
js
.
ethereum
.
NodeInfo
())
v
,
_
:=
call
.
Otto
.
ToValue
(
js
.
ethereum
.
NodeInfo
())
return
v
}
}
func
(
js
*
jsre
)
peers
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
peers
(
call
otto
.
FunctionCall
)
otto
.
Value
{
return
js
.
re
.
ToVal
(
js
.
ethereum
.
PeersInfo
())
v
,
_
:=
call
.
Otto
.
ToValue
(
js
.
ethereum
.
PeersInfo
())
return
v
}
}
func
(
js
*
jsre
)
importChain
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
importChain
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
@@ -562,7 +593,8 @@ func (js *jsre) dumpBlock(call otto.FunctionCall) otto.Value {
...
@@ -562,7 +593,8 @@ func (js *jsre) dumpBlock(call otto.FunctionCall) otto.Value {
statedb
:=
state
.
New
(
block
.
Root
(),
js
.
ethereum
.
StateDb
())
statedb
:=
state
.
New
(
block
.
Root
(),
js
.
ethereum
.
StateDb
())
dump
:=
statedb
.
RawDump
()
dump
:=
statedb
.
RawDump
()
return
js
.
re
.
ToVal
(
dump
)
v
,
_
:=
call
.
Otto
.
ToValue
(
dump
)
return
v
}
}
func
(
js
*
jsre
)
waitForBlocks
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
waitForBlocks
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
@@ -611,7 +643,8 @@ func (js *jsre) waitForBlocks(call otto.FunctionCall) otto.Value {
...
@@ -611,7 +643,8 @@ func (js *jsre) waitForBlocks(call otto.FunctionCall) otto.Value {
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
case
height
=
<-
wait
:
case
height
=
<-
wait
:
}
}
return
js
.
re
.
ToVal
(
height
.
Uint64
())
v
,
_
:=
call
.
Otto
.
ToValue
(
height
.
Uint64
())
return
v
}
}
func
(
js
*
jsre
)
sleep
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
sleep
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
@@ -704,8 +737,8 @@ func (js *jsre) register(call otto.FunctionCall) otto.Value {
...
@@ -704,8 +737,8 @@ func (js *jsre) register(call otto.FunctionCall) otto.Value {
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
return
js
.
re
.
ToVal
(
contenthash
.
Hex
())
v
,
_
:=
call
.
Otto
.
ToValue
(
contenthash
.
Hex
())
return
v
}
}
func
(
js
*
jsre
)
registerUrl
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
registerUrl
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
@@ -764,7 +797,8 @@ func (js *jsre) getContractInfo(call otto.FunctionCall) otto.Value {
...
@@ -764,7 +797,8 @@ func (js *jsre) getContractInfo(call otto.FunctionCall) otto.Value {
fmt
.
Println
(
err
)
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
return
js
.
re
.
ToVal
(
info
)
v
,
_
:=
call
.
Otto
.
ToValue
(
info
)
return
v
}
}
func
(
js
*
jsre
)
startNatSpec
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
js
*
jsre
)
startNatSpec
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
...
cmd/geth/js.go
View file @
70867904
...
@@ -104,7 +104,7 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, interactive boo
...
@@ -104,7 +104,7 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, interactive boo
func
(
js
*
jsre
)
apiBindings
(
f
xeth
.
Frontend
)
{
func
(
js
*
jsre
)
apiBindings
(
f
xeth
.
Frontend
)
{
xe
:=
xeth
.
New
(
js
.
ethereum
,
f
)
xe
:=
xeth
.
New
(
js
.
ethereum
,
f
)
ethApi
:=
rpc
.
NewEthereumApi
(
xe
)
ethApi
:=
rpc
.
NewEthereumApi
(
xe
)
jeth
:=
rpc
.
NewJeth
(
ethApi
,
js
.
re
.
ToVal
,
js
.
re
)
jeth
:=
rpc
.
NewJeth
(
ethApi
,
js
.
re
)
js
.
re
.
Set
(
"jeth"
,
struct
{}{})
js
.
re
.
Set
(
"jeth"
,
struct
{}{})
t
,
_
:=
js
.
re
.
Get
(
"jeth"
)
t
,
_
:=
js
.
re
.
Get
(
"jeth"
)
...
...
cmd/geth/js_test.go
View file @
70867904
...
@@ -35,6 +35,7 @@ const (
...
@@ -35,6 +35,7 @@ const (
var
(
var
(
versionRE
=
regexp
.
MustCompile
(
strconv
.
Quote
(
`"compilerVersion":"`
+
solcVersion
+
`"`
))
versionRE
=
regexp
.
MustCompile
(
strconv
.
Quote
(
`"compilerVersion":"`
+
solcVersion
+
`"`
))
testNodeKey
=
crypto
.
ToECDSA
(
common
.
Hex2Bytes
(
"4b50fa71f5c3eeb8fdc452224b2395af2fcc3d125e06c32c82e048c0559db03f"
))
testGenesis
=
`{"`
+
testAddress
[
2
:
]
+
`": {"balance": "`
+
testBalance
+
`"}}`
testGenesis
=
`{"`
+
testAddress
[
2
:
]
+
`": {"balance": "`
+
testBalance
+
`"}}`
)
)
...
@@ -72,6 +73,7 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
...
@@ -72,6 +73,7 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
ks
:=
crypto
.
NewKeyStorePlain
(
filepath
.
Join
(
tmp
,
"keystore"
))
ks
:=
crypto
.
NewKeyStorePlain
(
filepath
.
Join
(
tmp
,
"keystore"
))
am
:=
accounts
.
NewManager
(
ks
)
am
:=
accounts
.
NewManager
(
ks
)
ethereum
,
err
:=
eth
.
New
(
&
eth
.
Config
{
ethereum
,
err
:=
eth
.
New
(
&
eth
.
Config
{
NodeKey
:
testNodeKey
,
DataDir
:
tmp
,
DataDir
:
tmp
,
AccountManager
:
am
,
AccountManager
:
am
,
MaxPeers
:
0
,
MaxPeers
:
0
,
...
@@ -122,7 +124,7 @@ func TestNodeInfo(t *testing.T) {
...
@@ -122,7 +124,7 @@ func TestNodeInfo(t *testing.T) {
}
}
defer
ethereum
.
Stop
()
defer
ethereum
.
Stop
()
defer
os
.
RemoveAll
(
tmp
)
defer
os
.
RemoveAll
(
tmp
)
want
:=
`{"DiscPort":0,"IP":"0.0.0.0","ListenAddr":"","Name":"test","NodeID":"
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","NodeUrl":"enode://00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@0.0.0.0:0","TCPPort":0,"Td":"0
"}`
want
:=
`{"DiscPort":0,"IP":"0.0.0.0","ListenAddr":"","Name":"test","NodeID":"
4cb2fc32924e94277bf94b5e4c983beedb2eabd5a0bc941db32202735c6625d020ca14a5963d1738af43b6ac0a711d61b1a06de931a499fe2aa0b1a132a902b5","NodeUrl":"enode://4cb2fc32924e94277bf94b5e4c983beedb2eabd5a0bc941db32202735c6625d020ca14a5963d1738af43b6ac0a711d61b1a06de931a499fe2aa0b1a132a902b5@0.0.0.0:0","TCPPort":0,"Td":"131072
"}`
checkEvalJSON
(
t
,
repl
,
`admin.nodeInfo()`
,
want
)
checkEvalJSON
(
t
,
repl
,
`admin.nodeInfo()`
,
want
)
}
}
...
...
cmd/geth/main.go
View file @
70867904
...
@@ -48,7 +48,7 @@ import _ "net/http/pprof"
...
@@ -48,7 +48,7 @@ import _ "net/http/pprof"
const
(
const
(
ClientIdentifier
=
"Geth"
ClientIdentifier
=
"Geth"
Version
=
"0.9.2
4
"
Version
=
"0.9.2
5
"
)
)
var
(
var
(
...
@@ -260,6 +260,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
...
@@ -260,6 +260,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
utils
.
AutoDAGFlag
,
utils
.
AutoDAGFlag
,
utils
.
NATFlag
,
utils
.
NATFlag
,
utils
.
NatspecEnabledFlag
,
utils
.
NatspecEnabledFlag
,
utils
.
NoDiscoverFlag
,
utils
.
NodeKeyFileFlag
,
utils
.
NodeKeyFileFlag
,
utils
.
NodeKeyHexFlag
,
utils
.
NodeKeyHexFlag
,
utils
.
RPCEnabledFlag
,
utils
.
RPCEnabledFlag
,
...
@@ -532,9 +533,9 @@ func importchain(ctx *cli.Context) {
...
@@ -532,9 +533,9 @@ func importchain(ctx *cli.Context) {
}
}
// force database flush
// force database flush
ethereum
.
BlockDb
()
.
Close
()
ethereum
.
BlockDb
()
.
Flush
()
ethereum
.
StateDb
()
.
Close
()
ethereum
.
StateDb
()
.
Flush
()
ethereum
.
ExtraDb
()
.
Close
()
ethereum
.
ExtraDb
()
.
Flush
()
fmt
.
Printf
(
"Import done in %v"
,
time
.
Since
(
start
))
fmt
.
Printf
(
"Import done in %v"
,
time
.
Since
(
start
))
...
@@ -629,9 +630,9 @@ func upgradeDb(ctx *cli.Context) {
...
@@ -629,9 +630,9 @@ func upgradeDb(ctx *cli.Context) {
}
}
// force database flush
// force database flush
ethereum
.
BlockDb
()
.
Close
()
ethereum
.
BlockDb
()
.
Flush
()
ethereum
.
StateDb
()
.
Close
()
ethereum
.
StateDb
()
.
Flush
()
ethereum
.
ExtraDb
()
.
Close
()
ethereum
.
ExtraDb
()
.
Flush
()
os
.
Remove
(
exportFile
)
os
.
Remove
(
exportFile
)
...
...
cmd/utils/flags.go
View file @
70867904
...
@@ -235,6 +235,10 @@ var (
...
@@ -235,6 +235,10 @@ var (
Usage
:
"NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)"
,
Usage
:
"NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)"
,
Value
:
"any"
,
Value
:
"any"
,
}
}
NoDiscoverFlag
=
cli
.
BoolFlag
{
Name
:
"nodiscover"
,
Usage
:
"Disables the peer discovery mechanism (manual peer addition)"
,
}
WhisperEnabledFlag
=
cli
.
BoolFlag
{
WhisperEnabledFlag
=
cli
.
BoolFlag
{
Name
:
"shh"
,
Name
:
"shh"
,
Usage
:
"Enable whisper"
,
Usage
:
"Enable whisper"
,
...
@@ -312,6 +316,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
...
@@ -312,6 +316,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
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
),
Discovery
:
!
ctx
.
GlobalBool
(
NoDiscoverFlag
.
Name
),
NodeKey
:
GetNodeKey
(
ctx
),
NodeKey
:
GetNodeKey
(
ctx
),
Shh
:
ctx
.
GlobalBool
(
WhisperEnabledFlag
.
Name
),
Shh
:
ctx
.
GlobalBool
(
WhisperEnabledFlag
.
Name
),
Dial
:
true
,
Dial
:
true
,
...
@@ -320,7 +325,6 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
...
@@ -320,7 +325,6 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
SolcPath
:
ctx
.
GlobalString
(
SolcPathFlag
.
Name
),
SolcPath
:
ctx
.
GlobalString
(
SolcPathFlag
.
Name
),
AutoDAG
:
ctx
.
GlobalBool
(
AutoDAGFlag
.
Name
)
||
ctx
.
GlobalBool
(
MiningEnabledFlag
.
Name
),
AutoDAG
:
ctx
.
GlobalBool
(
AutoDAGFlag
.
Name
)
||
ctx
.
GlobalBool
(
MiningEnabledFlag
.
Name
),
}
}
}
}
func
GetChain
(
ctx
*
cli
.
Context
)
(
*
core
.
ChainManager
,
common
.
Database
,
common
.
Database
)
{
func
GetChain
(
ctx
*
cli
.
Context
)
(
*
core
.
ChainManager
,
common
.
Database
,
common
.
Database
)
{
...
...
common/compiler/solidity.go
View file @
70867904
...
@@ -34,6 +34,8 @@ var (
...
@@ -34,6 +34,8 @@ var (
"file"
,
//
"file"
,
//
"--natspec-dev"
,
// Request to output the contract's Natspec developer documentation.
"--natspec-dev"
,
// Request to output the contract's Natspec developer documentation.
"file"
,
"file"
,
"--add-std"
,
"1"
,
}
}
)
)
...
...
core/block_processor.go
View file @
70867904
...
@@ -21,7 +21,7 @@ import (
...
@@ -21,7 +21,7 @@ import (
const
(
const
(
// must be bumped when consensus algorithm is changed, this forces the upgradedb
// must be bumped when consensus algorithm is changed, this forces the upgradedb
// command to be run (forces the blocks to be imported again using the new algorithm)
// command to be run (forces the blocks to be imported again using the new algorithm)
BlockChainVersion
=
2
BlockChainVersion
=
3
)
)
var
receiptsPre
=
[]
byte
(
"receipts-"
)
var
receiptsPre
=
[]
byte
(
"receipts-"
)
...
@@ -159,6 +159,9 @@ func (sm *BlockProcessor) RetryProcess(block *types.Block) (logs state.Logs, err
...
@@ -159,6 +159,9 @@ func (sm *BlockProcessor) RetryProcess(block *types.Block) (logs state.Logs, err
return
nil
,
ParentError
(
header
.
ParentHash
)
return
nil
,
ParentError
(
header
.
ParentHash
)
}
}
parent
:=
sm
.
bc
.
GetBlock
(
header
.
ParentHash
)
parent
:=
sm
.
bc
.
GetBlock
(
header
.
ParentHash
)
if
!
sm
.
Pow
.
Verify
(
block
)
{
return
nil
,
ValidationError
(
"Block's nonce is invalid (= %x)"
,
block
.
Nonce
)
}
return
sm
.
processWithParent
(
block
,
parent
)
return
sm
.
processWithParent
(
block
,
parent
)
}
}
...
@@ -299,7 +302,7 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow b
...
@@ -299,7 +302,7 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow b
a
:=
new
(
big
.
Int
)
.
Sub
(
block
.
GasLimit
,
parent
.
GasLimit
)
a
:=
new
(
big
.
Int
)
.
Sub
(
block
.
GasLimit
,
parent
.
GasLimit
)
a
.
Abs
(
a
)
a
.
Abs
(
a
)
b
:=
new
(
big
.
Int
)
.
Div
(
parent
.
GasLimit
,
params
.
GasLimitBoundDivisor
)
b
:=
new
(
big
.
Int
)
.
Div
(
parent
.
GasLimit
,
params
.
GasLimitBoundDivisor
)
if
!
(
a
.
Cmp
(
b
)
<
0
)
||
(
block
.
GasLimit
.
Cmp
(
params
.
MinGasLimit
)
==
-
1
)
{
if
!
(
a
.
Cmp
(
b
)
<
=
0
)
||
(
block
.
GasLimit
.
Cmp
(
params
.
MinGasLimit
)
==
-
1
)
{
return
fmt
.
Errorf
(
"GasLimit check failed for block %v (%v > %v)"
,
block
.
GasLimit
,
a
,
b
)
return
fmt
.
Errorf
(
"GasLimit check failed for block %v (%v > %v)"
,
block
.
GasLimit
,
a
,
b
)
}
}
...
...
core/chain_manager.go
View file @
70867904
...
@@ -750,7 +750,7 @@ out:
...
@@ -750,7 +750,7 @@ out:
func
blockErr
(
block
*
types
.
Block
,
err
error
)
{
func
blockErr
(
block
*
types
.
Block
,
err
error
)
{
h
:=
block
.
Header
()
h
:=
block
.
Header
()
glog
.
V
(
logger
.
Error
)
.
Infof
(
"
INVALID
block #%v (%x)
\n
"
,
h
.
Number
,
h
.
Hash
()
.
Bytes
())
glog
.
V
(
logger
.
Error
)
.
Infof
(
"
Bad
block #%v (%x)
\n
"
,
h
.
Number
,
h
.
Hash
()
.
Bytes
())
glog
.
V
(
logger
.
Error
)
.
Infoln
(
err
)
glog
.
V
(
logger
.
Error
)
.
Infoln
(
err
)
glog
.
V
(
logger
.
Debug
)
.
Infoln
(
block
)
glog
.
V
(
logger
.
Debug
)
.
Infoln
(
block
)
}
}
...
...
core/transaction_pool.go
View file @
70867904
...
@@ -25,6 +25,7 @@ var (
...
@@ -25,6 +25,7 @@ var (
ErrInsufficientFunds
=
errors
.
New
(
"Insufficient funds for gas * price + value"
)
ErrInsufficientFunds
=
errors
.
New
(
"Insufficient funds for gas * price + value"
)
ErrIntrinsicGas
=
errors
.
New
(
"Intrinsic gas too low"
)
ErrIntrinsicGas
=
errors
.
New
(
"Intrinsic gas too low"
)
ErrGasLimit
=
errors
.
New
(
"Exceeds block gas limit"
)
ErrGasLimit
=
errors
.
New
(
"Exceeds block gas limit"
)
ErrNegativeValue
=
errors
.
New
(
"Negative value"
)
)
)
const
txPoolQueueSize
=
50
const
txPoolQueueSize
=
50
...
@@ -125,6 +126,10 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
...
@@ -125,6 +126,10 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
return
ErrGasLimit
return
ErrGasLimit
}
}
if
tx
.
Amount
.
Cmp
(
common
.
Big0
)
<
0
{
return
ErrNegativeValue
}
total
:=
new
(
big
.
Int
)
.
Mul
(
tx
.
Price
,
tx
.
GasLimit
)
total
:=
new
(
big
.
Int
)
.
Mul
(
tx
.
Price
,
tx
.
GasLimit
)
total
.
Add
(
total
,
tx
.
Value
())
total
.
Add
(
total
,
tx
.
Value
())
if
pool
.
currentState
()
.
GetBalance
(
from
)
.
Cmp
(
total
)
<
0
{
if
pool
.
currentState
()
.
GetBalance
(
from
)
.
Cmp
(
total
)
<
0
{
...
...
core/transaction_pool_test.go
View file @
70867904
...
@@ -138,3 +138,17 @@ func TestRemoveTx(t *testing.T) {
...
@@ -138,3 +138,17 @@ func TestRemoveTx(t *testing.T) {
t
.
Error
(
"expected txs to be 0, got"
,
len
(
pool
.
txs
))
t
.
Error
(
"expected txs to be 0, got"
,
len
(
pool
.
txs
))
}
}
}
}
func
TestNegativeValue
(
t
*
testing
.
T
)
{
pool
,
key
:=
setupTxPool
()
tx
:=
transaction
()
tx
.
Value
()
.
Set
(
big
.
NewInt
(
-
1
))
tx
.
SignECDSA
(
key
)
from
,
_
:=
tx
.
From
()
pool
.
currentState
()
.
AddBalance
(
from
,
big
.
NewInt
(
1
))
err
:=
pool
.
Add
(
tx
)
if
err
!=
ErrNegativeValue
{
t
.
Error
(
"expected"
,
ErrNegativeValue
,
"got"
,
err
)
}
}
eth/backend.go
View file @
70867904
...
@@ -72,6 +72,7 @@ type Config struct {
...
@@ -72,6 +72,7 @@ type Config struct {
MaxPeers
int
MaxPeers
int
MaxPendingPeers
int
MaxPendingPeers
int
Discovery
bool
Port
string
Port
string
// Space-separated list of discovery node URLs
// Space-separated list of discovery node URLs
...
@@ -311,6 +312,7 @@ func New(config *Config) (*Ethereum, error) {
...
@@ -311,6 +312,7 @@ func New(config *Config) (*Ethereum, error) {
Name
:
config
.
Name
,
Name
:
config
.
Name
,
MaxPeers
:
config
.
MaxPeers
,
MaxPeers
:
config
.
MaxPeers
,
MaxPendingPeers
:
config
.
MaxPendingPeers
,
MaxPendingPeers
:
config
.
MaxPendingPeers
,
Discovery
:
config
.
Discovery
,
Protocols
:
protocols
,
Protocols
:
protocols
,
NAT
:
config
.
NAT
,
NAT
:
config
.
NAT
,
NoDial
:
!
config
.
Dial
,
NoDial
:
!
config
.
Dial
,
...
@@ -449,14 +451,10 @@ func (s *Ethereum) Start() error {
...
@@ -449,14 +451,10 @@ func (s *Ethereum) Start() error {
ClientString
:
s
.
net
.
Name
,
ClientString
:
s
.
net
.
Name
,
ProtocolVersion
:
ProtocolVersion
,
ProtocolVersion
:
ProtocolVersion
,
})
})
if
s
.
net
.
MaxPeers
>
0
{
err
:=
s
.
net
.
Start
()
err
:=
s
.
net
.
Start
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
}
// periodically flush databases
// periodically flush databases
go
s
.
syncDatabases
()
go
s
.
syncDatabases
()
...
...
eth/downloader/downloader.go
View file @
70867904
...
@@ -415,7 +415,7 @@ out:
...
@@ -415,7 +415,7 @@ out:
peer
.
Demote
()
peer
.
Demote
()
break
break
}
}
if
glog
.
V
(
logger
.
Debug
)
{
if
glog
.
V
(
logger
.
Debug
)
&&
len
(
blockPack
.
blocks
)
>
0
{
glog
.
Infof
(
"Added %d blocks from: %s
\n
"
,
len
(
blockPack
.
blocks
),
blockPack
.
peerId
)
glog
.
Infof
(
"Added %d blocks from: %s
\n
"
,
len
(
blockPack
.
blocks
),
blockPack
.
peerId
)
}
}
// Promote the peer and update it's idle state
// Promote the peer and update it's idle state
...
...
eth/sync.go
View file @
70867904
...
@@ -70,7 +70,6 @@ func (pm *ProtocolManager) processBlocks() error {
...
@@ -70,7 +70,6 @@ func (pm *ProtocolManager) processBlocks() error {
// Try to inset the blocks, drop the originating peer if there's an error
// Try to inset the blocks, drop the originating peer if there's an error
index
,
err
:=
pm
.
chainman
.
InsertChain
(
raw
)
index
,
err
:=
pm
.
chainman
.
InsertChain
(
raw
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Block insertion failed: %v"
,
err
)
pm
.
removePeer
(
blocks
[
index
]
.
OriginPeer
)
pm
.
removePeer
(
blocks
[
index
]
.
OriginPeer
)
pm
.
downloader
.
Cancel
()
pm
.
downloader
.
Cancel
()
return
err
return
err
...
...
jsre/jsre.go
View file @
70867904
...
@@ -20,8 +20,6 @@ It provides some helper functions to
...
@@ -20,8 +20,6 @@ It provides some helper functions to
*/
*/
type
JSRE
struct
{
type
JSRE
struct
{
assetPath
string
assetPath
string
vm
*
otto
.
Otto
evalQueue
chan
*
evalReq
evalQueue
chan
*
evalReq
stopEventLoop
chan
bool
stopEventLoop
chan
bool
loopWg
sync
.
WaitGroup
loopWg
sync
.
WaitGroup
...
@@ -35,68 +33,37 @@ type jsTimer struct {
...
@@ -35,68 +33,37 @@ type jsTimer struct {
call
otto
.
FunctionCall
call
otto
.
FunctionCall
}
}
// evalResult is a structure to store the result of any serialized vm execution
// evalReq is a serialized vm execution request processed by runEventLoop.
type
evalResult
struct
{
result
otto
.
Value
err
error
}
// evalReq is a serialized vm execution request put in evalQueue and processed by runEventLoop
type
evalReq
struct
{
type
evalReq
struct
{
fn
func
(
res
*
evalResult
)
fn
func
(
vm
*
otto
.
Otto
)
done
chan
bool
done
chan
bool
res
evalResult
}
}
// runtime must be stopped with Stop() after use and cannot be used after stopping
// runtime must be stopped with Stop() after use and cannot be used after stopping
func
New
(
assetPath
string
)
*
JSRE
{
func
New
(
assetPath
string
)
*
JSRE
{
re
:=
&
JSRE
{
re
:=
&
JSRE
{
assetPath
:
assetPath
,
assetPath
:
assetPath
,
vm
:
otto
.
New
(),
evalQueue
:
make
(
chan
*
evalReq
),
stopEventLoop
:
make
(
chan
bool
),
}
}
// load prettyprint func definition
re
.
vm
.
Run
(
pp_js
)
re
.
vm
.
Set
(
"loadScript"
,
re
.
loadScript
)
re
.
evalQueue
=
make
(
chan
*
evalReq
)
re
.
stopEventLoop
=
make
(
chan
bool
)
re
.
loopWg
.
Add
(
1
)
re
.
loopWg
.
Add
(
1
)
go
re
.
runEventLoop
()
go
re
.
runEventLoop
()
re
.
Compile
(
"pp.js"
,
pp_js
)
// load prettyprint func definition
re
.
Set
(
"loadScript"
,
re
.
loadScript
)
return
re
return
re
}
}
// this function runs a piece of JS code either in a serialized way (when useEQ is true) or instantly, circumventing the evalQueue
// This function runs the main event loop from a goroutine that is started
func
(
self
*
JSRE
)
run
(
src
interface
{},
useEQ
bool
)
(
value
otto
.
Value
,
err
error
)
{
// when JSRE is created. Use Stop() before exiting to properly stop it.
if
useEQ
{
// The event loop processes vm access requests from the evalQueue in a
done
:=
make
(
chan
bool
)
// serialized way and calls timer callback functions at the appropriate time.
req
:=
&
evalReq
{
fn
:
func
(
res
*
evalResult
)
{
res
.
result
,
res
.
err
=
self
.
vm
.
Run
(
src
)
},
done
:
done
,
}
self
.
evalQueue
<-
req
<-
done
return
req
.
res
.
result
,
req
.
res
.
err
}
else
{
return
self
.
vm
.
Run
(
src
)
}
}
/*
// Exported functions always access the vm through the event queue. You can
This function runs the main event loop from a goroutine that is started
// call the functions of the otto vm directly to circumvent the queue. These
when JSRE is created. Use Stop() before exiting to properly stop it.
// functions should be used if and only if running a routine that was already
The event loop processes vm access requests from the evalQueue in a
// called from JS through an RPC call.
serialized way and calls timer callback functions at the appropriate time.
Exported functions always access the vm through the event queue. You can
call the functions of the otto vm directly to circumvent the queue. These
functions should be used if and only if running a routine that was already
called from JS through an RPC call.
*/
func
(
self
*
JSRE
)
runEventLoop
()
{
func
(
self
*
JSRE
)
runEventLoop
()
{
vm
:=
otto
.
New
()
registry
:=
map
[
*
jsTimer
]
*
jsTimer
{}
registry
:=
map
[
*
jsTimer
]
*
jsTimer
{}
ready
:=
make
(
chan
*
jsTimer
)
ready
:=
make
(
chan
*
jsTimer
)
...
@@ -143,10 +110,10 @@ func (self *JSRE) runEventLoop() {
...
@@ -143,10 +110,10 @@ func (self *JSRE) runEventLoop() {
}
}
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
self
.
vm
.
Set
(
"setTimeout"
,
setTimeout
)
vm
.
Set
(
"setTimeout"
,
setTimeout
)
self
.
vm
.
Set
(
"setInterval"
,
setInterval
)
vm
.
Set
(
"setInterval"
,
setInterval
)
self
.
vm
.
Set
(
"clearTimeout"
,
clearTimeout
)
vm
.
Set
(
"clearTimeout"
,
clearTimeout
)
self
.
vm
.
Set
(
"clearInterval"
,
clearTimeout
)
vm
.
Set
(
"clearInterval"
,
clearTimeout
)
var
waitForCallbacks
bool
var
waitForCallbacks
bool
...
@@ -166,8 +133,7 @@ loop:
...
@@ -166,8 +133,7 @@ loop:
arguments
=
make
([]
interface
{},
1
)
arguments
=
make
([]
interface
{},
1
)
}
}
arguments
[
0
]
=
timer
.
call
.
ArgumentList
[
0
]
arguments
[
0
]
=
timer
.
call
.
ArgumentList
[
0
]
_
,
err
:=
self
.
vm
.
Call
(
`Function.call.call`
,
nil
,
arguments
...
)
_
,
err
:=
vm
.
Call
(
`Function.call.call`
,
nil
,
arguments
...
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
"js error:"
,
err
,
arguments
)
fmt
.
Println
(
"js error:"
,
err
,
arguments
)
}
}
...
@@ -179,10 +145,10 @@ loop:
...
@@ -179,10 +145,10 @@ loop:
break
loop
break
loop
}
}
}
}
case
evalR
eq
:=
<-
self
.
evalQueue
:
case
r
eq
:=
<-
self
.
evalQueue
:
// run the code, send the result back
// run the code, send the result back
evalReq
.
fn
(
&
evalReq
.
res
)
req
.
fn
(
vm
)
close
(
evalR
eq
.
done
)
close
(
r
eq
.
done
)
if
waitForCallbacks
&&
(
len
(
registry
)
==
0
)
{
if
waitForCallbacks
&&
(
len
(
registry
)
==
0
)
{
break
loop
break
loop
}
}
...
@@ -201,6 +167,14 @@ loop:
...
@@ -201,6 +167,14 @@ loop:
self
.
loopWg
.
Done
()
self
.
loopWg
.
Done
()
}
}
// do schedules the given function on the event loop.
func
(
self
*
JSRE
)
do
(
fn
func
(
*
otto
.
Otto
))
{
done
:=
make
(
chan
bool
)
req
:=
&
evalReq
{
fn
,
done
}
self
.
evalQueue
<-
req
<-
done
}
// stops the event loop before exit, optionally waits for all timers to expire
// stops the event loop before exit, optionally waits for all timers to expire
func
(
self
*
JSRE
)
Stop
(
waitForCallbacks
bool
)
{
func
(
self
*
JSRE
)
Stop
(
waitForCallbacks
bool
)
{
self
.
stopEventLoop
<-
waitForCallbacks
self
.
stopEventLoop
<-
waitForCallbacks
...
@@ -210,119 +184,78 @@ func (self *JSRE) Stop(waitForCallbacks bool) {
...
@@ -210,119 +184,78 @@ func (self *JSRE) Stop(waitForCallbacks bool) {
// Exec(file) loads and runs the contents of a file
// Exec(file) loads and runs the contents of a file
// if a relative path is given, the jsre's assetPath is used
// if a relative path is given, the jsre's assetPath is used
func
(
self
*
JSRE
)
Exec
(
file
string
)
error
{
func
(
self
*
JSRE
)
Exec
(
file
string
)
error
{
return
self
.
exec
(
common
.
AbsolutePath
(
self
.
assetPath
,
file
),
true
)
code
,
err
:=
ioutil
.
ReadFile
(
common
.
AbsolutePath
(
self
.
assetPath
,
file
))
}
// circumvents the eval queue, see runEventLoop
func
(
self
*
JSRE
)
execWithoutEQ
(
file
string
)
error
{
return
self
.
exec
(
common
.
AbsolutePath
(
self
.
assetPath
,
file
),
false
)
}
func
(
self
*
JSRE
)
exec
(
path
string
,
useEQ
bool
)
error
{
code
,
err
:=
ioutil
.
ReadFile
(
path
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
_
,
err
=
self
.
run
(
code
,
useEQ
)
self
.
do
(
func
(
vm
*
otto
.
Otto
)
{
_
,
err
=
vm
.
Run
(
code
)
}
)
return
err
return
err
}
}
// assigns value v to a variable in the JS environment
//
Bind
assigns value v to a variable in the JS environment
func
(
self
*
JSRE
)
Bind
(
name
string
,
v
interface
{})
(
err
error
)
{
// This method is deprecated, use Set.
self
.
Set
(
name
,
v
)
func
(
self
*
JSRE
)
Bind
(
name
string
,
v
interface
{})
error
{
return
return
self
.
Set
(
name
,
v
)
}
}
// runs a piece of JS code
// Run runs a piece of JS code.
func
(
self
*
JSRE
)
Run
(
code
string
)
(
otto
.
Value
,
error
)
{
func
(
self
*
JSRE
)
Run
(
code
string
)
(
v
otto
.
Value
,
err
error
)
{
return
self
.
run
(
code
,
true
)
self
.
do
(
func
(
vm
*
otto
.
Otto
)
{
v
,
err
=
vm
.
Run
(
code
)
})
return
v
,
err
}
}
// returns the value of a variable in the JS environment
// Get returns the value of a variable in the JS environment.
func
(
self
*
JSRE
)
Get
(
ns
string
)
(
otto
.
Value
,
error
)
{
func
(
self
*
JSRE
)
Get
(
ns
string
)
(
v
otto
.
Value
,
err
error
)
{
done
:=
make
(
chan
bool
)
self
.
do
(
func
(
vm
*
otto
.
Otto
)
{
v
,
err
=
vm
.
Get
(
ns
)
})
req
:=
&
evalReq
{
return
v
,
err
fn
:
func
(
res
*
evalResult
)
{
res
.
result
,
res
.
err
=
self
.
vm
.
Get
(
ns
)
},
done
:
done
,
}
self
.
evalQueue
<-
req
<-
done
return
req
.
res
.
result
,
req
.
res
.
err
}
}
// assigns value v to a variable in the JS environment
// Set assigns value v to a variable in the JS environment.
func
(
self
*
JSRE
)
Set
(
ns
string
,
v
interface
{})
error
{
func
(
self
*
JSRE
)
Set
(
ns
string
,
v
interface
{})
(
err
error
)
{
done
:=
make
(
chan
bool
)
self
.
do
(
func
(
vm
*
otto
.
Otto
)
{
err
=
vm
.
Set
(
ns
,
v
)
})
req
:=
&
evalReq
{
return
err
fn
:
func
(
res
*
evalResult
)
{
res
.
err
=
self
.
vm
.
Set
(
ns
,
v
)
},
done
:
done
,
}
self
.
evalQueue
<-
req
<-
done
return
req
.
res
.
err
}
}
/*
// loadScript executes a JS script from inside the currently executing JS code.
Executes a JS script from inside the currently executing JS code.
Should only be called from inside an RPC routine.
*/
func
(
self
*
JSRE
)
loadScript
(
call
otto
.
FunctionCall
)
otto
.
Value
{
func
(
self
*
JSRE
)
loadScript
(
call
otto
.
FunctionCall
)
otto
.
Value
{
file
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
file
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
if
err
!=
nil
{
// TODO: throw exception
return
otto
.
FalseValue
()
return
otto
.
FalseValue
()
}
}
if
err
:=
self
.
execWithoutEQ
(
file
);
err
!=
nil
{
// loadScript is only called from inside js
file
=
common
.
AbsolutePath
(
self
.
assetPath
,
file
)
source
,
err
:=
ioutil
.
ReadFile
(
file
)
if
err
!=
nil
{
// TODO: throw exception
return
otto
.
FalseValue
()
}
if
_
,
err
:=
compileAndRun
(
call
.
Otto
,
file
,
source
);
err
!=
nil
{
// TODO: throw exception
fmt
.
Println
(
"err:"
,
err
)
fmt
.
Println
(
"err:"
,
err
)
return
otto
.
FalseValue
()
return
otto
.
FalseValue
()
}
}
// TODO: return evaluation result
return
otto
.
TrueValue
()
return
otto
.
TrueValue
()
}
}
//
uses the "prettyPrint" JS function to format a value
//
PrettyPrint writes v to standard output.
func
(
self
*
JSRE
)
PrettyPrint
(
v
interface
{})
(
val
otto
.
Value
,
err
error
)
{
func
(
self
*
JSRE
)
PrettyPrint
(
v
interface
{})
(
val
otto
.
Value
,
err
error
)
{
var
method
otto
.
Value
var
method
otto
.
Value
v
,
err
=
self
.
ToValue
(
v
)
self
.
do
(
func
(
vm
*
otto
.
Otto
)
{
val
,
err
=
vm
.
ToValue
(
v
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
method
,
err
=
self
.
vm
.
Get
(
"prettyPrint"
)
method
,
err
=
vm
.
Get
(
"prettyPrint"
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
return
method
.
Call
(
method
,
v
)
val
,
err
=
method
.
Call
(
method
,
val
)
}
})
return
val
,
err
// creates an otto value from a go type (serialized version)
func
(
self
*
JSRE
)
ToValue
(
v
interface
{})
(
otto
.
Value
,
error
)
{
done
:=
make
(
chan
bool
)
req
:=
&
evalReq
{
fn
:
func
(
res
*
evalResult
)
{
res
.
result
,
res
.
err
=
self
.
vm
.
ToValue
(
v
)
},
done
:
done
,
}
self
.
evalQueue
<-
req
<-
done
return
req
.
res
.
result
,
req
.
res
.
err
}
// creates an otto value from a go type (non-serialized version)
func
(
self
*
JSRE
)
ToVal
(
v
interface
{})
otto
.
Value
{
result
,
err
:=
self
.
vm
.
ToValue
(
v
)
if
err
!=
nil
{
fmt
.
Println
(
"Value unknown:"
,
err
)
return
otto
.
UndefinedValue
()
}
return
result
}
}
//
evaluates JS function and returns result in a pretty printed string format
//
Eval evaluates JS function and returns result in a pretty printed string format.
func
(
self
*
JSRE
)
Eval
(
code
string
)
(
s
string
,
err
error
)
{
func
(
self
*
JSRE
)
Eval
(
code
string
)
(
s
string
,
err
error
)
{
var
val
otto
.
Value
var
val
otto
.
Value
val
,
err
=
self
.
Run
(
code
)
val
,
err
=
self
.
Run
(
code
)
...
@@ -336,12 +269,16 @@ func (self *JSRE) Eval(code string) (s string, err error) {
...
@@ -336,12 +269,16 @@ func (self *JSRE) Eval(code string) (s string, err error) {
return
fmt
.
Sprintf
(
"%v"
,
val
),
nil
return
fmt
.
Sprintf
(
"%v"
,
val
),
nil
}
}
// compiles and then runs a piece of JS code
// Compile compiles and then runs a piece of JS code.
func
(
self
*
JSRE
)
Compile
(
fn
string
,
src
interface
{})
error
{
func
(
self
*
JSRE
)
Compile
(
filename
string
,
src
interface
{})
(
err
error
)
{
script
,
err
:=
self
.
vm
.
Compile
(
fn
,
src
)
self
.
do
(
func
(
vm
*
otto
.
Otto
)
{
_
,
err
=
compileAndRun
(
vm
,
filename
,
src
)
})
if
err
!=
nil
{
return
err
return
err
}
func
compileAndRun
(
vm
*
otto
.
Otto
,
filename
string
,
src
interface
{})
(
otto
.
Value
,
error
)
{
script
,
err
:=
vm
.
Compile
(
filename
,
src
)
if
err
!=
nil
{
return
otto
.
Value
{},
err
}
}
self
.
run
(
script
,
true
)
return
vm
.
Run
(
script
)
return
nil
}
}
jsre/jsre_test.go
View file @
70867904
package
jsre
package
jsre
import
(
import
(
"github.com/robertkrimen/otto"
"io/ioutil"
"io/ioutil"
"os"
"os"
"testing"
"testing"
"time"
"time"
"github.com/robertkrimen/otto"
)
)
type
testNativeObjectBinding
struct
{
type
testNativeObjectBinding
struct
{}
toVal
func
(
interface
{})
otto
.
Value
}
type
msg
struct
{
type
msg
struct
{
Msg
string
Msg
string
...
@@ -21,7 +20,8 @@ func (no *testNativeObjectBinding) TestMethod(call otto.FunctionCall) otto.Value
...
@@ -21,7 +20,8 @@ func (no *testNativeObjectBinding) TestMethod(call otto.FunctionCall) otto.Value
if
err
!=
nil
{
if
err
!=
nil
{
return
otto
.
UndefinedValue
()
return
otto
.
UndefinedValue
()
}
}
return
no
.
toVal
(
&
msg
{
m
})
v
,
_
:=
call
.
Otto
.
ToValue
(
&
msg
{
m
})
return
v
}
}
func
TestExec
(
t
*
testing
.
T
)
{
func
TestExec
(
t
*
testing
.
T
)
{
...
@@ -74,7 +74,7 @@ func TestNatto(t *testing.T) {
...
@@ -74,7 +74,7 @@ func TestNatto(t *testing.T) {
func
TestBind
(
t
*
testing
.
T
)
{
func
TestBind
(
t
*
testing
.
T
)
{
jsre
:=
New
(
"/tmp"
)
jsre
:=
New
(
"/tmp"
)
jsre
.
Bind
(
"no"
,
&
testNativeObjectBinding
{
jsre
.
ToVal
})
jsre
.
Bind
(
"no"
,
&
testNativeObjectBinding
{})
val
,
err
:=
jsre
.
Run
(
`no.TestMethod("testMsg")`
)
val
,
err
:=
jsre
.
Run
(
`no.TestMethod("testMsg")`
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
p2p/discover/database.go
View file @
70867904
...
@@ -47,6 +47,7 @@ var (
...
@@ -47,6 +47,7 @@ var (
nodeDBDiscoverRoot
=
":discover"
nodeDBDiscoverRoot
=
":discover"
nodeDBDiscoverPing
=
nodeDBDiscoverRoot
+
":lastping"
nodeDBDiscoverPing
=
nodeDBDiscoverRoot
+
":lastping"
nodeDBDiscoverPong
=
nodeDBDiscoverRoot
+
":lastpong"
nodeDBDiscoverPong
=
nodeDBDiscoverRoot
+
":lastpong"
nodeDBDiscoverFindFails
=
nodeDBDiscoverRoot
+
":findfail"
)
)
// newNodeDB creates a new node database for storing and retrieving infos about
// newNodeDB creates a new node database for storing and retrieving infos about
...
@@ -275,6 +276,16 @@ func (db *nodeDB) updateLastPong(id NodeID, instance time.Time) error {
...
@@ -275,6 +276,16 @@ func (db *nodeDB) updateLastPong(id NodeID, instance time.Time) error {
return
db
.
storeInt64
(
makeKey
(
id
,
nodeDBDiscoverPong
),
instance
.
Unix
())
return
db
.
storeInt64
(
makeKey
(
id
,
nodeDBDiscoverPong
),
instance
.
Unix
())
}
}
// findFails retrieves the number of findnode failures since bonding.
func
(
db
*
nodeDB
)
findFails
(
id
NodeID
)
int
{
return
int
(
db
.
fetchInt64
(
makeKey
(
id
,
nodeDBDiscoverFindFails
)))
}
// updateFindFails updates the number of findnode failures since bonding.
func
(
db
*
nodeDB
)
updateFindFails
(
id
NodeID
,
fails
int
)
error
{
return
db
.
storeInt64
(
makeKey
(
id
,
nodeDBDiscoverFindFails
),
int64
(
fails
))
}
// querySeeds retrieves a batch of nodes to be used as potential seed servers
// querySeeds retrieves a batch of nodes to be used as potential seed servers
// during bootstrapping the node into the network.
// during bootstrapping the node into the network.
//
//
...
...
p2p/discover/database_test.go
View file @
70867904
...
@@ -93,6 +93,7 @@ func TestNodeDBFetchStore(t *testing.T) {
...
@@ -93,6 +93,7 @@ func TestNodeDBFetchStore(t *testing.T) {
30303
,
30303
,
)
)
inst
:=
time
.
Now
()
inst
:=
time
.
Now
()
num
:=
314
db
,
_
:=
newNodeDB
(
""
,
Version
,
NodeID
{})
db
,
_
:=
newNodeDB
(
""
,
Version
,
NodeID
{})
defer
db
.
close
()
defer
db
.
close
()
...
@@ -117,6 +118,16 @@ func TestNodeDBFetchStore(t *testing.T) {
...
@@ -117,6 +118,16 @@ func TestNodeDBFetchStore(t *testing.T) {
if
stored
:=
db
.
lastPong
(
node
.
ID
);
stored
.
Unix
()
!=
inst
.
Unix
()
{
if
stored
:=
db
.
lastPong
(
node
.
ID
);
stored
.
Unix
()
!=
inst
.
Unix
()
{
t
.
Errorf
(
"pong: value mismatch: have %v, want %v"
,
stored
,
inst
)
t
.
Errorf
(
"pong: value mismatch: have %v, want %v"
,
stored
,
inst
)
}
}
// Check fetch/store operations on a node findnode-failure object
if
stored
:=
db
.
findFails
(
node
.
ID
);
stored
!=
0
{
t
.
Errorf
(
"find-node fails: non-existing object: %v"
,
stored
)
}
if
err
:=
db
.
updateFindFails
(
node
.
ID
,
num
);
err
!=
nil
{
t
.
Errorf
(
"find-node fails: failed to update: %v"
,
err
)
}
if
stored
:=
db
.
findFails
(
node
.
ID
);
stored
!=
num
{
t
.
Errorf
(
"find-node fails: value mismatch: have %v, want %v"
,
stored
,
num
)
}
// Check fetch/store operations on an actual node object
// Check fetch/store operations on an actual node object
if
stored
:=
db
.
node
(
node
.
ID
);
stored
!=
nil
{
if
stored
:=
db
.
node
(
node
.
ID
);
stored
!=
nil
{
t
.
Errorf
(
"node: non-existing object: %v"
,
stored
)
t
.
Errorf
(
"node: non-existing object: %v"
,
stored
)
...
...
p2p/discover/table.go
View file @
70867904
...
@@ -27,6 +27,7 @@ const (
...
@@ -27,6 +27,7 @@ const (
nBuckets
=
hashBits
+
1
// Number of buckets
nBuckets
=
hashBits
+
1
// Number of buckets
maxBondingPingPongs
=
16
maxBondingPingPongs
=
16
maxFindnodeFailures
=
5
)
)
type
Table
struct
{
type
Table
struct
{
...
@@ -190,6 +191,12 @@ func (tab *Table) Lookup(targetID NodeID) []*Node {
...
@@ -190,6 +191,12 @@ func (tab *Table) Lookup(targetID NodeID) []*Node {
result
:=
tab
.
closest
(
target
,
bucketSize
)
result
:=
tab
.
closest
(
target
,
bucketSize
)
tab
.
mutex
.
Unlock
()
tab
.
mutex
.
Unlock
()
// If the result set is empty, all nodes were dropped, refresh
if
len
(
result
.
entries
)
==
0
{
tab
.
refresh
()
return
nil
}
for
{
for
{
// ask the alpha closest nodes that we haven't asked yet
// ask the alpha closest nodes that we haven't asked yet
for
i
:=
0
;
i
<
len
(
result
.
entries
)
&&
pendingQueries
<
alpha
;
i
++
{
for
i
:=
0
;
i
<
len
(
result
.
entries
)
&&
pendingQueries
<
alpha
;
i
++
{
...
@@ -198,7 +205,19 @@ func (tab *Table) Lookup(targetID NodeID) []*Node {
...
@@ -198,7 +205,19 @@ func (tab *Table) Lookup(targetID NodeID) []*Node {
asked
[
n
.
ID
]
=
true
asked
[
n
.
ID
]
=
true
pendingQueries
++
pendingQueries
++
go
func
()
{
go
func
()
{
r
,
_
:=
tab
.
net
.
findnode
(
n
.
ID
,
n
.
addr
(),
targetID
)
// Find potential neighbors to bond with
r
,
err
:=
tab
.
net
.
findnode
(
n
.
ID
,
n
.
addr
(),
targetID
)
if
err
!=
nil
{
// Bump the failure counter to detect and evacuate non-bonded entries
fails
:=
tab
.
db
.
findFails
(
n
.
ID
)
+
1
tab
.
db
.
updateFindFails
(
n
.
ID
,
fails
)
glog
.
V
(
logger
.
Detail
)
.
Infof
(
"Bumping failures for %x: %d"
,
n
.
ID
[
:
8
],
fails
)
if
fails
>=
maxFindnodeFailures
{
glog
.
V
(
logger
.
Detail
)
.
Infof
(
"Evacuating node %x: %d findnode failures"
,
n
.
ID
[
:
8
],
fails
)
tab
.
del
(
n
)
}
}
reply
<-
tab
.
bondall
(
r
)
reply
<-
tab
.
bondall
(
r
)
}()
}()
}
}
...
@@ -219,8 +238,23 @@ func (tab *Table) Lookup(targetID NodeID) []*Node {
...
@@ -219,8 +238,23 @@ func (tab *Table) Lookup(targetID NodeID) []*Node {
return
result
.
entries
return
result
.
entries
}
}
// refresh performs a lookup for a random target to keep buckets full.
// refresh performs a lookup for a random target to keep buckets full, or seeds
// the table if it is empty (initial bootstrap or discarded faulty peers).
func
(
tab
*
Table
)
refresh
()
{
func
(
tab
*
Table
)
refresh
()
{
seed
:=
true
// If the discovery table is empty, seed with previously known nodes
tab
.
mutex
.
Lock
()
for
_
,
bucket
:=
range
tab
.
buckets
{
if
len
(
bucket
.
entries
)
>
0
{
seed
=
false
break
}
}
tab
.
mutex
.
Unlock
()
// If the table is not empty, try to refresh using the live entries
if
!
seed
{
// The Kademlia paper specifies that the bucket refresh should
// The Kademlia paper specifies that the bucket refresh should
// perform a refresh in the least recently used bucket. We cannot
// perform a refresh in the least recently used bucket. We cannot
// adhere to this because the findnode target is a 512bit value
// adhere to this because the findnode target is a 512bit value
...
@@ -230,19 +264,27 @@ func (tab *Table) refresh() {
...
@@ -230,19 +264,27 @@ func (tab *Table) refresh() {
// We perform a lookup with a random target instead.
// We perform a lookup with a random target instead.
var
target
NodeID
var
target
NodeID
rand
.
Read
(
target
[
:
])
rand
.
Read
(
target
[
:
])
result
:=
tab
.
Lookup
(
target
)
result
:=
tab
.
Lookup
(
target
)
if
len
(
result
)
==
0
{
if
len
(
result
)
==
0
{
// Lookup failed, seed after all
seed
=
true
}
}
if
seed
{
// Pick a batch of previously know seeds to lookup with
// Pick a batch of previously know seeds to lookup with
seeds
:=
tab
.
db
.
querySeeds
(
10
)
seeds
:=
tab
.
db
.
querySeeds
(
10
)
for
_
,
seed
:=
range
seeds
{
for
_
,
seed
:=
range
seeds
{
glog
.
V
(
logger
.
Debug
)
.
Infoln
(
"Seeding network with"
,
seed
)
glog
.
V
(
logger
.
Debug
)
.
Infoln
(
"Seeding network with"
,
seed
)
}
}
// Bootstrap the table with a self lookup
nodes
:=
append
(
tab
.
nursery
,
seeds
...
)
all
:=
tab
.
bondall
(
append
(
tab
.
nursery
,
seeds
...
))
tab
.
mutex
.
Lock
(
)
// Bond with all the seed nodes (will pingpong only if failed recently
)
tab
.
add
(
all
)
bonded
:=
tab
.
bondall
(
nodes
)
tab
.
mutex
.
Unlock
()
if
len
(
bonded
)
>
0
{
tab
.
Lookup
(
tab
.
self
.
ID
)
tab
.
Lookup
(
tab
.
self
.
ID
)
}
// TODO: the Kademlia paper says that we're supposed to perform
// TODO: the Kademlia paper says that we're supposed to perform
// random lookups in all buckets further away than our closest neighbor.
// random lookups in all buckets further away than our closest neighbor.
}
}
...
@@ -305,8 +347,16 @@ func (tab *Table) bondall(nodes []*Node) (result []*Node) {
...
@@ -305,8 +347,16 @@ func (tab *Table) bondall(nodes []*Node) (result []*Node) {
// If pinged is true, the remote node has just pinged us and one half
// If pinged is true, the remote node has just pinged us and one half
// of the process can be skipped.
// of the process can be skipped.
func
(
tab
*
Table
)
bond
(
pinged
bool
,
id
NodeID
,
addr
*
net
.
UDPAddr
,
tcpPort
uint16
)
(
*
Node
,
error
)
{
func
(
tab
*
Table
)
bond
(
pinged
bool
,
id
NodeID
,
addr
*
net
.
UDPAddr
,
tcpPort
uint16
)
(
*
Node
,
error
)
{
var
n
*
Node
// Retrieve a previously known node and any recent findnode failures
if
n
=
tab
.
db
.
node
(
id
);
n
==
nil
{
node
,
fails
:=
tab
.
db
.
node
(
id
),
0
if
node
!=
nil
{
fails
=
tab
.
db
.
findFails
(
id
)
}
// If the node is unknown (non-bonded) or failed (remotely unknown), bond from scratch
var
result
error
if
node
==
nil
||
fails
>
0
{
glog
.
V
(
logger
.
Detail
)
.
Infof
(
"Bonding %x: known=%v, fails=%v"
,
id
[
:
8
],
node
!=
nil
,
fails
)
tab
.
bondmu
.
Lock
()
tab
.
bondmu
.
Lock
()
w
:=
tab
.
bonding
[
id
]
w
:=
tab
.
bonding
[
id
]
if
w
!=
nil
{
if
w
!=
nil
{
...
@@ -325,18 +375,24 @@ func (tab *Table) bond(pinged bool, id NodeID, addr *net.UDPAddr, tcpPort uint16
...
@@ -325,18 +375,24 @@ func (tab *Table) bond(pinged bool, id NodeID, addr *net.UDPAddr, tcpPort uint16
delete
(
tab
.
bonding
,
id
)
delete
(
tab
.
bonding
,
id
)
tab
.
bondmu
.
Unlock
()
tab
.
bondmu
.
Unlock
()
}
}
n
=
w
.
n
// Retrieve the bonding results
if
w
.
err
!=
nil
{
result
=
w
.
err
return
nil
,
w
.
err
if
result
==
nil
{
node
=
w
.
n
}
}
}
}
// Even if bonding temporarily failed, give the node a chance
if
node
!=
nil
{
tab
.
mutex
.
Lock
()
tab
.
mutex
.
Lock
()
defer
tab
.
mutex
.
Unlock
()
defer
tab
.
mutex
.
Unlock
()
b
:=
tab
.
buckets
[
logdist
(
tab
.
self
.
sha
,
n
.
sha
)]
if
!
b
.
bump
(
n
)
{
b
:=
tab
.
buckets
[
logdist
(
tab
.
self
.
sha
,
node
.
sha
)]
tab
.
pingreplace
(
n
,
b
)
if
!
b
.
bump
(
node
)
{
tab
.
pingreplace
(
node
,
b
)
}
tab
.
db
.
updateFindFails
(
id
,
0
)
}
}
return
n
,
nil
return
n
ode
,
result
}
}
func
(
tab
*
Table
)
pingpong
(
w
*
bondproc
,
pinged
bool
,
id
NodeID
,
addr
*
net
.
UDPAddr
,
tcpPort
uint16
)
{
func
(
tab
*
Table
)
pingpong
(
w
*
bondproc
,
pinged
bool
,
id
NodeID
,
addr
*
net
.
UDPAddr
,
tcpPort
uint16
)
{
...
@@ -414,6 +470,21 @@ outer:
...
@@ -414,6 +470,21 @@ outer:
}
}
}
}
// del removes an entry from the node table (used to evacuate failed/non-bonded
// discovery peers).
func
(
tab
*
Table
)
del
(
node
*
Node
)
{
tab
.
mutex
.
Lock
()
defer
tab
.
mutex
.
Unlock
()
bucket
:=
tab
.
buckets
[
logdist
(
tab
.
self
.
sha
,
node
.
sha
)]
for
i
:=
range
bucket
.
entries
{
if
bucket
.
entries
[
i
]
.
ID
==
node
.
ID
{
bucket
.
entries
=
append
(
bucket
.
entries
[
:
i
],
bucket
.
entries
[
i
+
1
:
]
...
)
return
}
}
}
func
(
b
*
bucket
)
bump
(
n
*
Node
)
bool
{
func
(
b
*
bucket
)
bump
(
n
*
Node
)
bool
{
for
i
:=
range
b
.
entries
{
for
i
:=
range
b
.
entries
{
if
b
.
entries
[
i
]
.
ID
==
n
.
ID
{
if
b
.
entries
[
i
]
.
ID
==
n
.
ID
{
...
...
p2p/server.go
View file @
70867904
...
@@ -55,6 +55,10 @@ type Server struct {
...
@@ -55,6 +55,10 @@ type Server struct {
// Zero defaults to preset values.
// Zero defaults to preset values.
MaxPendingPeers
int
MaxPendingPeers
int
// Discovery specifies whether the peer discovery mechanism should be started
// or not. Disabling is usually useful for protocol debugging (manual topology).
Discovery
bool
// 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
...
@@ -237,9 +241,26 @@ func (srv *Server) AddPeer(node *discover.Node) {
...
@@ -237,9 +241,26 @@ func (srv *Server) AddPeer(node *discover.Node) {
func
(
srv
*
Server
)
Self
()
*
discover
.
Node
{
func
(
srv
*
Server
)
Self
()
*
discover
.
Node
{
srv
.
lock
.
Lock
()
srv
.
lock
.
Lock
()
defer
srv
.
lock
.
Unlock
()
defer
srv
.
lock
.
Unlock
()
// If the server's not running, return an empty node
if
!
srv
.
running
{
if
!
srv
.
running
{
return
&
discover
.
Node
{
IP
:
net
.
ParseIP
(
"0.0.0.0"
)}
return
&
discover
.
Node
{
IP
:
net
.
ParseIP
(
"0.0.0.0"
)}
}
}
// If the node is running but discovery is off, manually assemble the node infos
if
srv
.
ntab
==
nil
{
// Inbound connections disabled, use zero address
if
srv
.
listener
==
nil
{
return
&
discover
.
Node
{
IP
:
net
.
ParseIP
(
"0.0.0.0"
),
ID
:
discover
.
PubkeyID
(
&
srv
.
PrivateKey
.
PublicKey
)}
}
// Otherwise inject the listener address too
addr
:=
srv
.
listener
.
Addr
()
.
(
*
net
.
TCPAddr
)
return
&
discover
.
Node
{
ID
:
discover
.
PubkeyID
(
&
srv
.
PrivateKey
.
PublicKey
),
IP
:
addr
.
IP
,
TCP
:
uint16
(
addr
.
Port
),
}
}
// Otherwise return the live node infos
return
srv
.
ntab
.
Self
()
return
srv
.
ntab
.
Self
()
}
}
...
@@ -275,9 +296,6 @@ func (srv *Server) Start() (err error) {
...
@@ -275,9 +296,6 @@ func (srv *Server) Start() (err error) {
if
srv
.
PrivateKey
==
nil
{
if
srv
.
PrivateKey
==
nil
{
return
fmt
.
Errorf
(
"Server.PrivateKey must be set to a non-nil key"
)
return
fmt
.
Errorf
(
"Server.PrivateKey must be set to a non-nil key"
)
}
}
if
srv
.
MaxPeers
<=
0
{
return
fmt
.
Errorf
(
"Server.MaxPeers must be > 0"
)
}
if
srv
.
newTransport
==
nil
{
if
srv
.
newTransport
==
nil
{
srv
.
newTransport
=
newRLPX
srv
.
newTransport
=
newRLPX
}
}
...
@@ -293,15 +311,22 @@ func (srv *Server) Start() (err error) {
...
@@ -293,15 +311,22 @@ func (srv *Server) Start() (err error) {
srv
.
peerOpDone
=
make
(
chan
struct
{})
srv
.
peerOpDone
=
make
(
chan
struct
{})
// node table
// node table
if
srv
.
Discovery
{
ntab
,
err
:=
discover
.
ListenUDP
(
srv
.
PrivateKey
,
srv
.
ListenAddr
,
srv
.
NAT
,
srv
.
NodeDatabase
)
ntab
,
err
:=
discover
.
ListenUDP
(
srv
.
PrivateKey
,
srv
.
ListenAddr
,
srv
.
NAT
,
srv
.
NodeDatabase
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
srv
.
ntab
=
ntab
srv
.
ntab
=
ntab
dialer
:=
newDialState
(
srv
.
StaticNodes
,
srv
.
ntab
,
srv
.
MaxPeers
/
2
)
}
dynPeers
:=
srv
.
MaxPeers
/
2
if
!
srv
.
Discovery
{
dynPeers
=
0
}
dialer
:=
newDialState
(
srv
.
StaticNodes
,
srv
.
ntab
,
dynPeers
)
// handshake
// handshake
srv
.
ourHandshake
=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
Name
:
srv
.
Name
,
ID
:
ntab
.
Self
()
.
ID
}
srv
.
ourHandshake
=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
Name
:
srv
.
Name
,
ID
:
discover
.
PubkeyID
(
&
srv
.
PrivateKey
.
PublicKey
)
}
for
_
,
p
:=
range
srv
.
Protocols
{
for
_
,
p
:=
range
srv
.
Protocols
{
srv
.
ourHandshake
.
Caps
=
append
(
srv
.
ourHandshake
.
Caps
,
p
.
cap
())
srv
.
ourHandshake
.
Caps
=
append
(
srv
.
ourHandshake
.
Caps
,
p
.
cap
())
}
}
...
@@ -457,7 +482,9 @@ running:
...
@@ -457,7 +482,9 @@ running:
}
}
// Terminate discovery. If there is a running lookup it will terminate soon.
// Terminate discovery. If there is a running lookup it will terminate soon.
if
srv
.
ntab
!=
nil
{
srv
.
ntab
.
Close
()
srv
.
ntab
.
Close
()
}
// Disconnect all peers.
// Disconnect all peers.
for
_
,
p
:=
range
peers
{
for
_
,
p
:=
range
peers
{
p
.
Disconnect
(
DiscQuitting
)
p
.
Disconnect
(
DiscQuitting
)
...
@@ -489,7 +516,7 @@ func (srv *Server) encHandshakeChecks(peers map[discover.NodeID]*Peer, c *conn)
...
@@ -489,7 +516,7 @@ func (srv *Server) encHandshakeChecks(peers map[discover.NodeID]*Peer, c *conn)
return
DiscTooManyPeers
return
DiscTooManyPeers
case
peers
[
c
.
id
]
!=
nil
:
case
peers
[
c
.
id
]
!=
nil
:
return
DiscAlreadyConnected
return
DiscAlreadyConnected
case
c
.
id
==
srv
.
ntab
.
Self
()
.
ID
:
case
c
.
id
==
srv
.
Self
()
.
ID
:
return
DiscSelf
return
DiscSelf
default
:
default
:
return
nil
return
nil
...
...
rpc/jeth.go
View file @
70867904
...
@@ -3,18 +3,18 @@ package rpc
...
@@ -3,18 +3,18 @@ package rpc
import
(
import
(
"encoding/json"
"encoding/json"
"fmt"
"fmt"
"github.com/ethereum/go-ethereum/jsre"
"github.com/ethereum/go-ethereum/jsre"
"github.com/robertkrimen/otto"
"github.com/robertkrimen/otto"
)
)
type
Jeth
struct
{
type
Jeth
struct
{
ethApi
*
EthereumApi
ethApi
*
EthereumApi
toVal
func
(
interface
{})
otto
.
Value
re
*
jsre
.
JSRE
re
*
jsre
.
JSRE
}
}
func
NewJeth
(
ethApi
*
EthereumApi
,
toVal
func
(
interface
{})
otto
.
Value
,
re
*
jsre
.
JSRE
)
*
Jeth
{
func
NewJeth
(
ethApi
*
EthereumApi
,
re
*
jsre
.
JSRE
)
*
Jeth
{
return
&
Jeth
{
ethApi
,
toVal
,
re
}
return
&
Jeth
{
ethApi
,
re
}
}
}
func
(
self
*
Jeth
)
err
(
call
otto
.
FunctionCall
,
code
int
,
msg
string
,
id
interface
{})
(
response
otto
.
Value
)
{
func
(
self
*
Jeth
)
err
(
call
otto
.
FunctionCall
,
code
int
,
msg
string
,
id
interface
{})
(
response
otto
.
Value
)
{
...
...
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