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
821e01b0
Commit
821e01b0
authored
Jun 19, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd/geth, eth/fetcher: initial metrics support
Conflicts: cmd/geth/admin.go
parent
22c7ce01
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
974 additions
and
0 deletions
+974
-0
admin.go
cmd/geth/admin.go
+960
-0
fetcher.go
eth/fetcher/fetcher.go
+14
-0
No files found.
cmd/geth/admin.go
0 → 100644
View file @
821e01b0
package
main
import
(
"encoding/json"
"errors"
"fmt"
"math/big"
"strconv"
"time"
"github.com/rcrowley/go-metrics"
"github.com/ethereum/ethash"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/compiler"
"github.com/ethereum/go-ethereum/common/natspec"
"github.com/ethereum/go-ethereum/common/resolver"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/xeth"
"github.com/robertkrimen/otto"
"gopkg.in/fatih/set.v0"
)
/*
node admin bindings
*/
func
(
js
*
jsre
)
adminBindings
()
{
ethO
,
_
:=
js
.
re
.
Get
(
"eth"
)
eth
:=
ethO
.
Object
()
eth
.
Set
(
"pendingTransactions"
,
js
.
pendingTransactions
)
eth
.
Set
(
"resend"
,
js
.
resend
)
eth
.
Set
(
"sign"
,
js
.
sign
)
js
.
re
.
Set
(
"admin"
,
struct
{}{})
t
,
_
:=
js
.
re
.
Get
(
"admin"
)
admin
:=
t
.
Object
()
admin
.
Set
(
"addPeer"
,
js
.
addPeer
)
admin
.
Set
(
"startRPC"
,
js
.
startRPC
)
admin
.
Set
(
"stopRPC"
,
js
.
stopRPC
)
admin
.
Set
(
"nodeInfo"
,
js
.
nodeInfo
)
admin
.
Set
(
"peers"
,
js
.
peers
)
admin
.
Set
(
"newAccount"
,
js
.
newAccount
)
admin
.
Set
(
"unlock"
,
js
.
unlock
)
admin
.
Set
(
"import"
,
js
.
importChain
)
admin
.
Set
(
"export"
,
js
.
exportChain
)
admin
.
Set
(
"verbosity"
,
js
.
verbosity
)
admin
.
Set
(
"progress"
,
js
.
syncProgress
)
admin
.
Set
(
"setSolc"
,
js
.
setSolc
)
admin
.
Set
(
"contractInfo"
,
struct
{}{})
t
,
_
=
admin
.
Get
(
"contractInfo"
)
cinfo
:=
t
.
Object
()
// newRegistry officially not documented temporary option
cinfo
.
Set
(
"start"
,
js
.
startNatSpec
)
cinfo
.
Set
(
"stop"
,
js
.
stopNatSpec
)
cinfo
.
Set
(
"newRegistry"
,
js
.
newRegistry
)
cinfo
.
Set
(
"get"
,
js
.
getContractInfo
)
cinfo
.
Set
(
"register"
,
js
.
register
)
cinfo
.
Set
(
"registerUrl"
,
js
.
registerUrl
)
// cinfo.Set("verify", js.verify)
admin
.
Set
(
"miner"
,
struct
{}{})
t
,
_
=
admin
.
Get
(
"miner"
)
miner
:=
t
.
Object
()
miner
.
Set
(
"start"
,
js
.
startMining
)
miner
.
Set
(
"stop"
,
js
.
stopMining
)
miner
.
Set
(
"hashrate"
,
js
.
hashrate
)
miner
.
Set
(
"setExtra"
,
js
.
setExtra
)
miner
.
Set
(
"setGasPrice"
,
js
.
setGasPrice
)
miner
.
Set
(
"startAutoDAG"
,
js
.
startAutoDAG
)
miner
.
Set
(
"stopAutoDAG"
,
js
.
stopAutoDAG
)
miner
.
Set
(
"makeDAG"
,
js
.
makeDAG
)
admin
.
Set
(
"txPool"
,
struct
{}{})
t
,
_
=
admin
.
Get
(
"txPool"
)
txPool
:=
t
.
Object
()
txPool
.
Set
(
"pending"
,
js
.
allPendingTransactions
)
txPool
.
Set
(
"queued"
,
js
.
allQueuedTransactions
)
admin
.
Set
(
"debug"
,
struct
{}{})
t
,
_
=
admin
.
Get
(
"debug"
)
debug
:=
t
.
Object
()
js
.
re
.
Set
(
"sleep"
,
js
.
sleep
)
debug
.
Set
(
"backtrace"
,
js
.
backtrace
)
debug
.
Set
(
"printBlock"
,
js
.
printBlock
)
debug
.
Set
(
"dumpBlock"
,
js
.
dumpBlock
)
debug
.
Set
(
"getBlockRlp"
,
js
.
getBlockRlp
)
debug
.
Set
(
"setHead"
,
js
.
setHead
)
debug
.
Set
(
"processBlock"
,
js
.
debugBlock
)
debug
.
Set
(
"seedhash"
,
js
.
seedHash
)
debug
.
Set
(
"insertBlock"
,
js
.
insertBlockRlp
)
// undocumented temporary
debug
.
Set
(
"waitForBlocks"
,
js
.
waitForBlocks
)
admin
.
Set
(
"metrics"
,
js
.
metrics
)
}
// generic helper to getBlock by Number/Height or Hex depending on autodetected input
// if argument is missing the current block is returned
// if block is not found or there is problem with decoding
// the appropriate value is returned and block is guaranteed to be nil
func
(
js
*
jsre
)
getBlock
(
call
otto
.
FunctionCall
)
(
*
types
.
Block
,
error
)
{
var
block
*
types
.
Block
if
len
(
call
.
ArgumentList
)
>
0
{
if
call
.
Argument
(
0
)
.
IsNumber
()
{
num
,
_
:=
call
.
Argument
(
0
)
.
ToInteger
()
block
=
js
.
ethereum
.
ChainManager
()
.
GetBlockByNumber
(
uint64
(
num
))
}
else
if
call
.
Argument
(
0
)
.
IsString
()
{
hash
,
_
:=
call
.
Argument
(
0
)
.
ToString
()
block
=
js
.
ethereum
.
ChainManager
()
.
GetBlock
(
common
.
HexToHash
(
hash
))
}
else
{
return
nil
,
errors
.
New
(
"invalid argument for dump. Either hex string or number"
)
}
}
else
{
block
=
js
.
ethereum
.
ChainManager
()
.
CurrentBlock
()
}
if
block
==
nil
{
return
nil
,
errors
.
New
(
"block not found"
)
}
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
)
allPendingTransactions
(
call
otto
.
FunctionCall
)
otto
.
Value
{
txs
:=
js
.
ethereum
.
TxPool
()
.
GetTransactions
()
ltxs
:=
make
([]
*
tx
,
len
(
txs
))
for
i
,
tx
:=
range
txs
{
// no need to check err
ltxs
[
i
]
=
newTx
(
tx
)
}
v
,
_
:=
call
.
Otto
.
ToValue
(
ltxs
)
return
v
}
func
(
js
*
jsre
)
allQueuedTransactions
(
call
otto
.
FunctionCall
)
otto
.
Value
{
txs
:=
js
.
ethereum
.
TxPool
()
.
GetQueuedTransactions
()
ltxs
:=
make
([]
*
tx
,
len
(
txs
))
for
i
,
tx
:=
range
txs
{
// no need to check err
ltxs
[
i
]
=
newTx
(
tx
)
}
v
,
_
:=
call
.
Otto
.
ToValue
(
ltxs
)
return
v
}
func
(
js
*
jsre
)
pendingTransactions
(
call
otto
.
FunctionCall
)
otto
.
Value
{
txs
:=
js
.
ethereum
.
TxPool
()
.
GetTransactions
()
// grab the accounts from the account manager. This will help with determening which
// transactions should be returned.
accounts
,
err
:=
js
.
ethereum
.
AccountManager
()
.
Accounts
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
// Add the accouns to a new set
accountSet
:=
set
.
New
()
for
_
,
account
:=
range
accounts
{
accountSet
.
Add
(
account
.
Address
)
}
//ltxs := make([]*tx, len(txs))
var
ltxs
[]
*
tx
for
_
,
tx
:=
range
txs
{
if
from
,
_
:=
tx
.
From
();
accountSet
.
Has
(
from
)
{
ltxs
=
append
(
ltxs
,
newTx
(
tx
))
}
}
v
,
_
:=
call
.
Otto
.
ToValue
(
ltxs
)
return
v
}
func
(
js
*
jsre
)
resend
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
==
0
{
fmt
.
Println
(
"first argument must be a transaction"
)
return
otto
.
FalseValue
()
}
v
,
err
:=
call
.
Argument
(
0
)
.
Export
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
if
tx
,
ok
:=
v
.
(
*
tx
);
ok
{
gl
,
gp
:=
tx
.
GasLimit
,
tx
.
GasPrice
if
len
(
call
.
ArgumentList
)
>
1
{
gp
=
call
.
Argument
(
1
)
.
String
()
}
if
len
(
call
.
ArgumentList
)
>
2
{
gl
=
call
.
Argument
(
2
)
.
String
()
}
ret
,
err
:=
js
.
xeth
.
Transact
(
tx
.
From
,
tx
.
To
,
tx
.
Nonce
,
tx
.
Value
,
gl
,
gp
,
tx
.
Data
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
js
.
ethereum
.
TxPool
()
.
RemoveTransactions
(
types
.
Transactions
{
tx
.
tx
})
v
,
_
:=
call
.
Otto
.
ToValue
(
ret
)
return
v
}
fmt
.
Println
(
"first argument must be a transaction"
)
return
otto
.
FalseValue
()
}
func
(
js
*
jsre
)
sign
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
!=
2
{
fmt
.
Println
(
"requires 2 arguments: eth.sign(signer, data)"
)
return
otto
.
UndefinedValue
()
}
signer
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
data
,
err
:=
call
.
Argument
(
1
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
signed
,
err
:=
js
.
xeth
.
Sign
(
signer
,
data
,
false
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
v
,
_
:=
call
.
Otto
.
ToValue
(
signed
)
return
v
}
func
(
js
*
jsre
)
debugBlock
(
call
otto
.
FunctionCall
)
otto
.
Value
{
block
,
err
:=
js
.
getBlock
(
call
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
tstart
:=
time
.
Now
()
old
:=
vm
.
Debug
if
len
(
call
.
ArgumentList
)
>
1
{
vm
.
Debug
,
_
=
call
.
Argument
(
1
)
.
ToBoolean
()
}
_
,
err
=
js
.
ethereum
.
BlockProcessor
()
.
RetryProcess
(
block
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
r
,
_
:=
call
.
Otto
.
ToValue
(
map
[
string
]
interface
{}{
"success"
:
false
,
"time"
:
time
.
Since
(
tstart
)
.
Seconds
()})
return
r
}
vm
.
Debug
=
old
r
,
_
:=
call
.
Otto
.
ToValue
(
map
[
string
]
interface
{}{
"success"
:
true
,
"time"
:
time
.
Since
(
tstart
)
.
Seconds
()})
return
r
}
func
(
js
*
jsre
)
insertBlockRlp
(
call
otto
.
FunctionCall
)
otto
.
Value
{
tstart
:=
time
.
Now
()
var
block
types
.
Block
if
call
.
Argument
(
0
)
.
IsString
()
{
blockRlp
,
_
:=
call
.
Argument
(
0
)
.
ToString
()
err
:=
rlp
.
DecodeBytes
(
common
.
Hex2Bytes
(
blockRlp
),
&
block
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
}
old
:=
vm
.
Debug
vm
.
Debug
=
true
_
,
err
:=
js
.
ethereum
.
BlockProcessor
()
.
RetryProcess
(
&
block
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
r
,
_
:=
call
.
Otto
.
ToValue
(
map
[
string
]
interface
{}{
"success"
:
false
,
"time"
:
time
.
Since
(
tstart
)
.
Seconds
()})
return
r
}
vm
.
Debug
=
old
r
,
_
:=
call
.
Otto
.
ToValue
(
map
[
string
]
interface
{}{
"success"
:
true
,
"time"
:
time
.
Since
(
tstart
)
.
Seconds
()})
return
r
}
func
(
js
*
jsre
)
setHead
(
call
otto
.
FunctionCall
)
otto
.
Value
{
block
,
err
:=
js
.
getBlock
(
call
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
js
.
ethereum
.
ChainManager
()
.
SetHead
(
block
)
return
otto
.
UndefinedValue
()
}
func
(
js
*
jsre
)
syncProgress
(
call
otto
.
FunctionCall
)
otto
.
Value
{
pending
,
cached
,
importing
,
eta
:=
js
.
ethereum
.
Downloader
()
.
Stats
()
v
,
_
:=
call
.
Otto
.
ToValue
(
map
[
string
]
interface
{}{
"pending"
:
pending
,
"cached"
:
cached
,
"importing"
:
importing
,
"estimate"
:
(
eta
/
time
.
Second
*
time
.
Second
)
.
String
(),
})
return
v
}
func
(
js
*
jsre
)
getBlockRlp
(
call
otto
.
FunctionCall
)
otto
.
Value
{
block
,
err
:=
js
.
getBlock
(
call
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
encoded
,
_
:=
rlp
.
EncodeToBytes
(
block
)
v
,
_
:=
call
.
Otto
.
ToValue
(
fmt
.
Sprintf
(
"%x"
,
encoded
))
return
v
}
func
(
js
*
jsre
)
setExtra
(
call
otto
.
FunctionCall
)
otto
.
Value
{
extra
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
if
len
(
extra
)
>
1024
{
fmt
.
Println
(
"error: cannot exceed 1024 bytes"
)
return
otto
.
UndefinedValue
()
}
js
.
ethereum
.
Miner
()
.
SetExtra
([]
byte
(
extra
))
return
otto
.
UndefinedValue
()
}
func
(
js
*
jsre
)
setGasPrice
(
call
otto
.
FunctionCall
)
otto
.
Value
{
gasPrice
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
js
.
ethereum
.
Miner
()
.
SetGasPrice
(
common
.
String2Big
(
gasPrice
))
return
otto
.
UndefinedValue
()
}
func
(
js
*
jsre
)
hashrate
(
call
otto
.
FunctionCall
)
otto
.
Value
{
v
,
_
:=
call
.
Otto
.
ToValue
(
js
.
ethereum
.
Miner
()
.
HashRate
())
return
v
}
func
(
js
*
jsre
)
makeDAG
(
call
otto
.
FunctionCall
)
otto
.
Value
{
blockNumber
,
err
:=
call
.
Argument
(
1
)
.
ToInteger
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
err
=
ethash
.
MakeDAG
(
uint64
(
blockNumber
),
""
)
if
err
!=
nil
{
return
otto
.
FalseValue
()
}
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
startAutoDAG
(
otto
.
FunctionCall
)
otto
.
Value
{
js
.
ethereum
.
StartAutoDAG
()
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
stopAutoDAG
(
otto
.
FunctionCall
)
otto
.
Value
{
js
.
ethereum
.
StopAutoDAG
()
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
backtrace
(
call
otto
.
FunctionCall
)
otto
.
Value
{
tracestr
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
glog
.
GetTraceLocation
()
.
Set
(
tracestr
)
return
otto
.
UndefinedValue
()
}
func
(
js
*
jsre
)
verbosity
(
call
otto
.
FunctionCall
)
otto
.
Value
{
v
,
err
:=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
glog
.
SetV
(
int
(
v
))
return
otto
.
UndefinedValue
()
}
func
(
js
*
jsre
)
startMining
(
call
otto
.
FunctionCall
)
otto
.
Value
{
var
(
threads
int64
err
error
)
if
len
(
call
.
ArgumentList
)
>
0
{
threads
,
err
=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
}
else
{
threads
=
int64
(
js
.
ethereum
.
MinerThreads
)
}
// switch on DAG autogeneration when miner starts
js
.
ethereum
.
StartAutoDAG
()
err
=
js
.
ethereum
.
StartMining
(
int
(
threads
))
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
stopMining
(
call
otto
.
FunctionCall
)
otto
.
Value
{
js
.
ethereum
.
StopMining
()
js
.
ethereum
.
StopAutoDAG
()
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
startRPC
(
call
otto
.
FunctionCall
)
otto
.
Value
{
addr
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
port
,
err
:=
call
.
Argument
(
1
)
.
ToInteger
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
corsDomain
:=
js
.
corsDomain
if
len
(
call
.
ArgumentList
)
>
2
{
corsDomain
,
err
=
call
.
Argument
(
2
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
}
config
:=
rpc
.
RpcConfig
{
ListenAddress
:
addr
,
ListenPort
:
uint
(
port
),
CorsDomain
:
corsDomain
,
}
xeth
:=
xeth
.
New
(
js
.
ethereum
,
nil
)
err
=
rpc
.
Start
(
xeth
,
config
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
stopRPC
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
rpc
.
Stop
()
==
nil
{
return
otto
.
TrueValue
()
}
return
otto
.
FalseValue
()
}
func
(
js
*
jsre
)
addPeer
(
call
otto
.
FunctionCall
)
otto
.
Value
{
nodeURL
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
err
=
js
.
ethereum
.
AddPeer
(
nodeURL
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
unlock
(
call
otto
.
FunctionCall
)
otto
.
Value
{
addr
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
seconds
,
err
:=
call
.
Argument
(
2
)
.
ToInteger
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
if
seconds
==
0
{
seconds
=
accounts
.
DefaultAccountUnlockDuration
}
arg
:=
call
.
Argument
(
1
)
var
passphrase
string
if
arg
.
IsUndefined
()
{
fmt
.
Println
(
"Please enter a passphrase now."
)
passphrase
,
err
=
utils
.
PromptPassword
(
"Passphrase: "
,
true
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
}
else
{
passphrase
,
err
=
arg
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
}
am
:=
js
.
ethereum
.
AccountManager
()
err
=
am
.
TimedUnlock
(
common
.
HexToAddress
(
addr
),
passphrase
,
time
.
Duration
(
seconds
)
*
time
.
Second
)
if
err
!=
nil
{
fmt
.
Printf
(
"Unlock account failed '%v'
\n
"
,
err
)
return
otto
.
FalseValue
()
}
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
newAccount
(
call
otto
.
FunctionCall
)
otto
.
Value
{
arg
:=
call
.
Argument
(
0
)
var
passphrase
string
if
arg
.
IsUndefined
()
{
fmt
.
Println
(
"The new account will be encrypted with a passphrase."
)
fmt
.
Println
(
"Please enter a passphrase now."
)
auth
,
err
:=
utils
.
PromptPassword
(
"Passphrase: "
,
true
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
confirm
,
err
:=
utils
.
PromptPassword
(
"Repeat Passphrase: "
,
false
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
if
auth
!=
confirm
{
fmt
.
Println
(
"Passphrases did not match."
)
return
otto
.
FalseValue
()
}
passphrase
=
auth
}
else
{
var
err
error
passphrase
,
err
=
arg
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
}
acct
,
err
:=
js
.
ethereum
.
AccountManager
()
.
NewAccount
(
passphrase
)
if
err
!=
nil
{
fmt
.
Printf
(
"Could not create the account: %v"
,
err
)
return
otto
.
UndefinedValue
()
}
v
,
_
:=
call
.
Otto
.
ToValue
(
acct
.
Address
.
Hex
())
return
v
}
func
(
js
*
jsre
)
nodeInfo
(
call
otto
.
FunctionCall
)
otto
.
Value
{
v
,
_
:=
call
.
Otto
.
ToValue
(
js
.
ethereum
.
NodeInfo
())
return
v
}
func
(
js
*
jsre
)
peers
(
call
otto
.
FunctionCall
)
otto
.
Value
{
v
,
_
:=
call
.
Otto
.
ToValue
(
js
.
ethereum
.
PeersInfo
())
return
v
}
func
(
js
*
jsre
)
importChain
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
==
0
{
fmt
.
Println
(
"require file name. admin.importChain(filename)"
)
return
otto
.
FalseValue
()
}
fn
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
if
err
:=
utils
.
ImportChain
(
js
.
ethereum
.
ChainManager
(),
fn
);
err
!=
nil
{
fmt
.
Println
(
"Import error: "
,
err
)
return
otto
.
FalseValue
()
}
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
exportChain
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
==
0
{
fmt
.
Println
(
"require file name: admin.exportChain(filename)"
)
return
otto
.
FalseValue
()
}
fn
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
if
err
:=
utils
.
ExportChain
(
js
.
ethereum
.
ChainManager
(),
fn
);
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
printBlock
(
call
otto
.
FunctionCall
)
otto
.
Value
{
block
,
err
:=
js
.
getBlock
(
call
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
fmt
.
Println
(
block
)
return
otto
.
UndefinedValue
()
}
func
(
js
*
jsre
)
dumpBlock
(
call
otto
.
FunctionCall
)
otto
.
Value
{
block
,
err
:=
js
.
getBlock
(
call
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
statedb
:=
state
.
New
(
block
.
Root
(),
js
.
ethereum
.
StateDb
())
dump
:=
statedb
.
RawDump
()
v
,
_
:=
call
.
Otto
.
ToValue
(
dump
)
return
v
}
func
(
js
*
jsre
)
waitForBlocks
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
>
2
{
fmt
.
Println
(
"requires 0, 1 or 2 arguments: admin.debug.waitForBlock(minHeight, timeout)"
)
return
otto
.
FalseValue
()
}
var
n
,
timeout
int64
var
timer
<-
chan
time
.
Time
var
height
*
big
.
Int
var
err
error
args
:=
len
(
call
.
ArgumentList
)
if
args
==
2
{
timeout
,
err
=
call
.
Argument
(
1
)
.
ToInteger
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
timer
=
time
.
NewTimer
(
time
.
Duration
(
timeout
)
*
time
.
Second
)
.
C
}
if
args
>=
1
{
n
,
err
=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
height
=
big
.
NewInt
(
n
)
}
if
args
==
0
{
height
=
js
.
xeth
.
CurrentBlock
()
.
Number
()
height
.
Add
(
height
,
common
.
Big1
)
}
wait
:=
js
.
wait
js
.
wait
<-
height
select
{
case
<-
timer
:
// if times out make sure the xeth loop does not block
go
func
()
{
select
{
case
wait
<-
nil
:
case
<-
wait
:
}
}()
return
otto
.
UndefinedValue
()
case
height
=
<-
wait
:
}
v
,
_
:=
call
.
Otto
.
ToValue
(
height
.
Uint64
())
return
v
}
func
(
js
*
jsre
)
metrics
(
call
otto
.
FunctionCall
)
otto
.
Value
{
// Iterate over all the metrics, and just dump for now
counters
:=
make
(
map
[
string
]
interface
{})
metrics
.
DefaultRegistry
.
Each
(
func
(
name
string
,
metric
interface
{})
{
switch
metric
:=
metric
.
(
type
)
{
case
metrics
.
Meter
:
counters
[
name
+
"( 1 min)"
]
=
int
(
metric
.
Rate1
()
*
60
)
counters
[
name
+
"( 5 min)"
]
=
int
(
metric
.
Rate5
()
*
300
)
counters
[
name
+
"(15 min)"
]
=
int
(
metric
.
Rate15
()
*
900
)
default
:
counters
[
name
]
=
"Unknown metric type"
}
})
// Flatten the counters into some metrics and return
v
,
_
:=
call
.
Otto
.
ToValue
(
counters
)
return
v
}
func
(
js
*
jsre
)
sleep
(
call
otto
.
FunctionCall
)
otto
.
Value
{
sec
,
err
:=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
time
.
Sleep
(
time
.
Duration
(
sec
)
*
time
.
Second
)
return
otto
.
UndefinedValue
()
}
func
(
js
*
jsre
)
setSolc
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
!=
1
{
fmt
.
Println
(
"needs 1 argument: admin.contractInfo.setSolc(solcPath)"
)
return
otto
.
FalseValue
()
}
solcPath
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
return
otto
.
FalseValue
()
}
solc
,
err
:=
js
.
xeth
.
SetSolc
(
solcPath
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
fmt
.
Println
(
solc
.
Info
())
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
register
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
!=
4
{
fmt
.
Println
(
"requires 4 arguments: admin.contractInfo.register(fromaddress, contractaddress, contract, filename)"
)
return
otto
.
UndefinedValue
()
}
sender
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
address
,
err
:=
call
.
Argument
(
1
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
raw
,
err
:=
call
.
Argument
(
2
)
.
Export
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
jsonraw
,
err
:=
json
.
Marshal
(
raw
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
var
contract
compiler
.
Contract
err
=
json
.
Unmarshal
(
jsonraw
,
&
contract
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
filename
,
err
:=
call
.
Argument
(
3
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
contenthash
,
err
:=
compiler
.
ExtractInfo
(
&
contract
,
filename
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
// sender and contract address are passed as hex strings
codeb
:=
js
.
xeth
.
CodeAtBytes
(
address
)
codehash
:=
common
.
BytesToHash
(
crypto
.
Sha3
(
codeb
))
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
registry
:=
resolver
.
New
(
js
.
xeth
)
_
,
err
=
registry
.
RegisterContentHash
(
common
.
HexToAddress
(
sender
),
codehash
,
contenthash
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
v
,
_
:=
call
.
Otto
.
ToValue
(
contenthash
.
Hex
())
return
v
}
func
(
js
*
jsre
)
registerUrl
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
!=
3
{
fmt
.
Println
(
"requires 3 arguments: admin.contractInfo.register(fromaddress, contenthash, filename)"
)
return
otto
.
FalseValue
()
}
sender
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
contenthash
,
err
:=
call
.
Argument
(
1
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
url
,
err
:=
call
.
Argument
(
2
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
registry
:=
resolver
.
New
(
js
.
xeth
)
_
,
err
=
registry
.
RegisterUrl
(
common
.
HexToAddress
(
sender
),
common
.
HexToHash
(
contenthash
),
url
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
getContractInfo
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
!=
1
{
fmt
.
Println
(
"requires 1 argument: admin.contractInfo.register(contractaddress)"
)
return
otto
.
FalseValue
()
}
addr
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
infoDoc
,
err
:=
natspec
.
FetchDocsForContract
(
addr
,
js
.
xeth
,
ds
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
var
info
compiler
.
ContractInfo
err
=
json
.
Unmarshal
(
infoDoc
,
&
info
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
UndefinedValue
()
}
v
,
_
:=
call
.
Otto
.
ToValue
(
info
)
return
v
}
func
(
js
*
jsre
)
startNatSpec
(
call
otto
.
FunctionCall
)
otto
.
Value
{
js
.
ethereum
.
NatSpec
=
true
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
stopNatSpec
(
call
otto
.
FunctionCall
)
otto
.
Value
{
js
.
ethereum
.
NatSpec
=
false
return
otto
.
TrueValue
()
}
func
(
js
*
jsre
)
newRegistry
(
call
otto
.
FunctionCall
)
otto
.
Value
{
if
len
(
call
.
ArgumentList
)
!=
1
{
fmt
.
Println
(
"requires 1 argument: admin.contractInfo.newRegistry(adminaddress)"
)
return
otto
.
FalseValue
()
}
addr
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
registry
:=
resolver
.
New
(
js
.
xeth
)
err
=
registry
.
CreateContracts
(
common
.
HexToAddress
(
addr
))
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
otto
.
FalseValue
()
}
return
otto
.
TrueValue
()
}
// internal transaction type which will allow us to resend transactions using `eth.resend`
type
tx
struct
{
tx
*
types
.
Transaction
To
string
From
string
Nonce
string
Value
string
Data
string
GasLimit
string
GasPrice
string
}
func
newTx
(
t
*
types
.
Transaction
)
*
tx
{
from
,
_
:=
t
.
From
()
var
to
string
if
t
:=
t
.
To
();
t
!=
nil
{
to
=
t
.
Hex
()
}
return
&
tx
{
tx
:
t
,
To
:
to
,
From
:
from
.
Hex
(),
Value
:
t
.
Amount
.
String
(),
Nonce
:
strconv
.
Itoa
(
int
(
t
.
Nonce
())),
Data
:
"0x"
+
common
.
Bytes2Hex
(
t
.
Data
()),
GasLimit
:
t
.
GasLimit
.
String
(),
GasPrice
:
t
.
GasPrice
()
.
String
(),
}
}
eth/fetcher/fetcher.go
View file @
821e01b0
...
@@ -7,6 +7,8 @@ import (
...
@@ -7,6 +7,8 @@ import (
"math/rand"
"math/rand"
"time"
"time"
"github.com/rcrowley/go-metrics"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger"
...
@@ -96,6 +98,11 @@ type Fetcher struct {
...
@@ -96,6 +98,11 @@ type Fetcher struct {
// Testing hooks
// Testing hooks
fetchingHook
func
([]
common
.
Hash
)
// Method to call upon starting a block fetch
fetchingHook
func
([]
common
.
Hash
)
// Method to call upon starting a block fetch
importedHook
func
(
*
types
.
Block
)
// Method to call upon successful block import
importedHook
func
(
*
types
.
Block
)
// Method to call upon successful block import
// Runtime metrics
announceStats
metrics
.
Meter
broadcastStats
metrics
.
Meter
discardStats
metrics
.
Meter
}
}
// New creates a block fetcher to retrieve blocks based on hash announcements.
// New creates a block fetcher to retrieve blocks based on hash announcements.
...
@@ -118,6 +125,9 @@ func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlo
...
@@ -118,6 +125,9 @@ func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlo
chainHeight
:
chainHeight
,
chainHeight
:
chainHeight
,
insertChain
:
insertChain
,
insertChain
:
insertChain
,
dropPeer
:
dropPeer
,
dropPeer
:
dropPeer
,
announceStats
:
metrics
.
GetOrRegisterMeter
(
"eth/Announced Blocks"
,
metrics
.
DefaultRegistry
),
broadcastStats
:
metrics
.
GetOrRegisterMeter
(
"eth/Propagated Blocks"
,
metrics
.
DefaultRegistry
),
discardStats
:
metrics
.
GetOrRegisterMeter
(
"eth/Discarded Blocks"
,
metrics
.
DefaultRegistry
),
}
}
}
}
...
@@ -229,6 +239,8 @@ func (f *Fetcher) loop() {
...
@@ -229,6 +239,8 @@ func (f *Fetcher) loop() {
case
notification
:=
<-
f
.
notify
:
case
notification
:=
<-
f
.
notify
:
// A block was announced, make sure the peer isn't DOSing us
// A block was announced, make sure the peer isn't DOSing us
f
.
announceStats
.
Mark
(
1
)
count
:=
f
.
announces
[
notification
.
origin
]
+
1
count
:=
f
.
announces
[
notification
.
origin
]
+
1
if
count
>
hashLimit
{
if
count
>
hashLimit
{
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Peer %s: exceeded outstanding announces (%d)"
,
notification
.
origin
,
hashLimit
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Peer %s: exceeded outstanding announces (%d)"
,
notification
.
origin
,
hashLimit
)
...
@@ -246,6 +258,7 @@ func (f *Fetcher) loop() {
...
@@ -246,6 +258,7 @@ func (f *Fetcher) loop() {
case
op
:=
<-
f
.
inject
:
case
op
:=
<-
f
.
inject
:
// A direct block insertion was requested, try and fill any pending gaps
// A direct block insertion was requested, try and fill any pending gaps
f
.
broadcastStats
.
Mark
(
1
)
f
.
enqueue
(
op
.
origin
,
op
.
block
)
f
.
enqueue
(
op
.
origin
,
op
.
block
)
case
hash
:=
<-
f
.
done
:
case
hash
:=
<-
f
.
done
:
...
@@ -364,6 +377,7 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) {
...
@@ -364,6 +377,7 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) {
// Discard any past or too distant blocks
// Discard any past or too distant blocks
if
dist
:=
int64
(
block
.
NumberU64
())
-
int64
(
f
.
chainHeight
());
dist
<
-
maxUncleDist
||
dist
>
maxQueueDist
{
if
dist
:=
int64
(
block
.
NumberU64
())
-
int64
(
f
.
chainHeight
());
dist
<
-
maxUncleDist
||
dist
>
maxQueueDist
{
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Peer %s: discarded block #%d [%x], distance %d"
,
peer
,
block
.
NumberU64
(),
hash
.
Bytes
()[
:
4
],
dist
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Peer %s: discarded block #%d [%x], distance %d"
,
peer
,
block
.
NumberU64
(),
hash
.
Bytes
()[
:
4
],
dist
)
f
.
discardStats
.
Mark
(
1
)
return
return
}
}
// Schedule the block for future importing
// Schedule the block for future importing
...
...
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