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
bde2ff03
Commit
bde2ff03
authored
Jun 23, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd/geth, rpc/api: move the metrics into the new console
parent
803b3c4a
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
69 additions
and
1003 deletions
+69
-1003
admin.go
cmd/geth/admin.go
+0
-1003
debug.go
rpc/api/debug.go
+64
-0
debug_js.go
rpc/api/debug_js.go
+5
-0
No files found.
cmd/geth/admin.go
deleted
100644 → 0
View file @
803b3c4a
package
main
import
(
"encoding/json"
"errors"
"fmt"
"math/big"
"strconv"
"strings"
"time"
"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/rcrowley/go-metrics"
"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
{
// Create a rate formatter
units
:=
[]
string
{
""
,
"K"
,
"M"
,
"G"
,
"T"
,
"E"
,
"P"
}
round
:=
func
(
value
float64
,
prec
int
)
string
{
unit
:=
0
for
value
>=
1000
{
unit
,
value
,
prec
=
unit
+
1
,
value
/
1000
,
2
}
return
fmt
.
Sprintf
(
fmt
.
Sprintf
(
"%%.%df%s"
,
prec
,
units
[
unit
]),
value
)
}
format
:=
func
(
total
float64
,
rate
float64
)
string
{
return
fmt
.
Sprintf
(
"%s (%s/s)"
,
round
(
total
,
0
),
round
(
rate
,
2
))
}
// Iterate over all the metrics, and just dump for now
counters
:=
make
(
map
[
string
]
interface
{})
metrics
.
DefaultRegistry
.
Each
(
func
(
name
string
,
metric
interface
{})
{
// Create or retrieve the counter hierarchy for this metric
root
,
parts
:=
counters
,
strings
.
Split
(
name
,
"/"
)
for
_
,
part
:=
range
parts
[
:
len
(
parts
)
-
1
]
{
if
_
,
ok
:=
root
[
part
];
!
ok
{
root
[
part
]
=
make
(
map
[
string
]
interface
{})
}
root
=
root
[
part
]
.
(
map
[
string
]
interface
{})
}
name
=
parts
[
len
(
parts
)
-
1
]
// Fill the counter with the metric details
switch
metric
:=
metric
.
(
type
)
{
case
metrics
.
Meter
:
root
[
name
]
=
map
[
string
]
interface
{}{
"Avg01Min"
:
format
(
metric
.
Rate1
()
*
60
,
metric
.
Rate1
()),
"Avg05Min"
:
format
(
metric
.
Rate5
()
*
300
,
metric
.
Rate5
()),
"Avg15Min"
:
format
(
metric
.
Rate15
()
*
900
,
metric
.
Rate15
()),
"Total"
:
format
(
float64
(
metric
.
Count
()),
metric
.
RateMean
()),
}
case
metrics
.
Timer
:
root
[
name
]
=
map
[
string
]
interface
{}{
"Avg01Min"
:
format
(
metric
.
Rate1
()
*
60
,
metric
.
Rate1
()),
"Avg05Min"
:
format
(
metric
.
Rate5
()
*
300
,
metric
.
Rate5
()),
"Avg15Min"
:
format
(
metric
.
Rate15
()
*
900
,
metric
.
Rate15
()),
"Count"
:
format
(
float64
(
metric
.
Count
()),
metric
.
RateMean
()),
"Maximum"
:
time
.
Duration
(
metric
.
Max
())
.
String
(),
"Minimum"
:
time
.
Duration
(
metric
.
Min
())
.
String
(),
"Percentile"
:
map
[
string
]
interface
{}{
"20"
:
time
.
Duration
(
metric
.
Percentile
(
0.2
))
.
String
(),
"50"
:
time
.
Duration
(
metric
.
Percentile
(
0.5
))
.
String
(),
"80"
:
time
.
Duration
(
metric
.
Percentile
(
0.8
))
.
String
(),
"95"
:
time
.
Duration
(
metric
.
Percentile
(
0.95
))
.
String
(),
"99"
:
time
.
Duration
(
metric
.
Percentile
(
0.99
))
.
String
(),
},
}
default
:
root
[
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
(),
}
}
rpc/api/debug.go
View file @
bde2ff03
...
...
@@ -2,6 +2,8 @@ package api
import
(
"fmt"
"strings"
"time"
"github.com/ethereum/ethash"
"github.com/ethereum/go-ethereum/core/state"
...
...
@@ -11,6 +13,7 @@ import (
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/shared"
"github.com/ethereum/go-ethereum/xeth"
"github.com/rcrowley/go-metrics"
)
const
(
...
...
@@ -26,6 +29,7 @@ var (
"debug_processBlock"
:
(
*
debugApi
)
.
ProcessBlock
,
"debug_seedHash"
:
(
*
debugApi
)
.
SeedHash
,
"debug_setHead"
:
(
*
debugApi
)
.
SetHead
,
"debug_metrics"
:
(
*
debugApi
)
.
Metrics
,
}
)
...
...
@@ -171,3 +175,63 @@ func (self *debugApi) SeedHash(req *shared.Request) (interface{}, error) {
return
nil
,
err
}
}
func
(
self
*
debugApi
)
Metrics
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
// Create a rate formatter
units
:=
[]
string
{
""
,
"K"
,
"M"
,
"G"
,
"T"
,
"E"
,
"P"
}
round
:=
func
(
value
float64
,
prec
int
)
string
{
unit
:=
0
for
value
>=
1000
{
unit
,
value
,
prec
=
unit
+
1
,
value
/
1000
,
2
}
return
fmt
.
Sprintf
(
fmt
.
Sprintf
(
"%%.%df%s"
,
prec
,
units
[
unit
]),
value
)
}
format
:=
func
(
total
float64
,
rate
float64
)
string
{
return
fmt
.
Sprintf
(
"%s (%s/s)"
,
round
(
total
,
0
),
round
(
rate
,
2
))
}
// Iterate over all the metrics, and just dump for now
counters
:=
make
(
map
[
string
]
interface
{})
metrics
.
DefaultRegistry
.
Each
(
func
(
name
string
,
metric
interface
{})
{
// Create or retrieve the counter hierarchy for this metric
root
,
parts
:=
counters
,
strings
.
Split
(
name
,
"/"
)
for
_
,
part
:=
range
parts
[
:
len
(
parts
)
-
1
]
{
if
_
,
ok
:=
root
[
part
];
!
ok
{
root
[
part
]
=
make
(
map
[
string
]
interface
{})
}
root
=
root
[
part
]
.
(
map
[
string
]
interface
{})
}
name
=
parts
[
len
(
parts
)
-
1
]
// Fill the counter with the metric details
switch
metric
:=
metric
.
(
type
)
{
case
metrics
.
Meter
:
root
[
name
]
=
map
[
string
]
interface
{}{
"Avg01Min"
:
format
(
metric
.
Rate1
()
*
60
,
metric
.
Rate1
()),
"Avg05Min"
:
format
(
metric
.
Rate5
()
*
300
,
metric
.
Rate5
()),
"Avg15Min"
:
format
(
metric
.
Rate15
()
*
900
,
metric
.
Rate15
()),
"Total"
:
format
(
float64
(
metric
.
Count
()),
metric
.
RateMean
()),
}
case
metrics
.
Timer
:
root
[
name
]
=
map
[
string
]
interface
{}{
"Avg01Min"
:
format
(
metric
.
Rate1
()
*
60
,
metric
.
Rate1
()),
"Avg05Min"
:
format
(
metric
.
Rate5
()
*
300
,
metric
.
Rate5
()),
"Avg15Min"
:
format
(
metric
.
Rate15
()
*
900
,
metric
.
Rate15
()),
"Count"
:
format
(
float64
(
metric
.
Count
()),
metric
.
RateMean
()),
"Maximum"
:
time
.
Duration
(
metric
.
Max
())
.
String
(),
"Minimum"
:
time
.
Duration
(
metric
.
Min
())
.
String
(),
"Percentile"
:
map
[
string
]
interface
{}{
"20"
:
time
.
Duration
(
metric
.
Percentile
(
0.2
))
.
String
(),
"50"
:
time
.
Duration
(
metric
.
Percentile
(
0.5
))
.
String
(),
"80"
:
time
.
Duration
(
metric
.
Percentile
(
0.8
))
.
String
(),
"95"
:
time
.
Duration
(
metric
.
Percentile
(
0.95
))
.
String
(),
"99"
:
time
.
Duration
(
metric
.
Percentile
(
0.99
))
.
String
(),
},
}
default
:
root
[
name
]
=
"Unknown metric type"
}
})
return
counters
,
nil
}
rpc/api/debug_js.go
View file @
bde2ff03
...
...
@@ -50,6 +50,11 @@ web3._extend({
],
properties:
[
new web3._extend.Property({
name: 'metrics',
getter: 'debug_metrics',
outputFormatter: function(obj) { return obj; }
})
]
});
`
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