added admin API

This commit is contained in:
Bas van Kervel 2015-06-09 16:06:51 +02:00 committed by Bas van Kervel
parent 08d72a9245
commit cc9ae39933
14 changed files with 613 additions and 203 deletions

228
rpc/api/admin.go Normal file
View File

@ -0,0 +1,228 @@
package api
import (
"fmt"
"io"
"os"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/shared"
"github.com/ethereum/go-ethereum/xeth"
)
const (
AdminVersion = "1.0.0"
importBatchSize = 2500
)
var (
// mapping between methods and handlers
AdminMapping = map[string]adminhandler{
// "admin_startRPC": (*adminApi).StartRPC,
// "admin_stopRPC": (*adminApi).StopRPC,
"admin_addPeer": (*adminApi).AddPeer,
"admin_peers": (*adminApi).Peers,
"admin_nodeInfo": (*adminApi).NodeInfo,
"admin_exportChain": (*adminApi).ExportChain,
"admin_importChain": (*adminApi).ImportChain,
"admin_verbosity": (*adminApi).Verbosity,
"admin_syncStatus": (*adminApi).SyncStatus,
"admin_setSolc": (*adminApi).SetSolc,
}
)
// admin callback handler
type adminhandler func(*adminApi, *shared.Request) (interface{}, error)
// admin api provider
type adminApi struct {
xeth *xeth.XEth
ethereum *eth.Ethereum
methods map[string]adminhandler
codec codec.ApiCoder
}
// create a new admin api instance
func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *adminApi {
return &adminApi{
xeth: xeth,
ethereum: ethereum,
methods: AdminMapping,
codec: coder.New(nil),
}
}
// collection with supported methods
func (self *adminApi) Methods() []string {
methods := make([]string, len(self.methods))
i := 0
for k := range self.methods {
methods[i] = k
i++
}
return methods
}
// Execute given request
func (self *adminApi) Execute(req *shared.Request) (interface{}, error) {
if callback, ok := self.methods[req.Method]; ok {
return callback(self, req)
}
return nil, &shared.NotImplementedError{req.Method}
}
func (self *adminApi) Name() string {
return AdminApiName
}
func (self *adminApi) AddPeer(req *shared.Request) (interface{}, error) {
args := new(AddPeerArgs)
if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
err := self.ethereum.AddPeer(args.Url)
if err == nil {
return true, nil
}
return false, err
}
func (self *adminApi) Peers(req *shared.Request) (interface{}, error) {
return self.ethereum.PeersInfo(), nil
}
func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) {
return false, nil
// Enable when http rpc interface is refactored to prevent import cycles
// args := new(StartRpcArgs)
// if err := self.codec.Decode(req.Params, &args); err != nil {
// return nil, shared.NewDecodeParamError(err.Error())
// }
//
// cfg := rpc.RpcConfig{
// ListenAddress: args.Address,
// ListenPort: args.Port,
// }
//
// err := rpc.Start(self.xeth, cfg)
// if err == nil {
// return true, nil
// }
// return false, err
}
func (self *adminApi) StopRPC(req *shared.Request) (interface{}, error) {
return false, nil
// Enable when http rpc interface is refactored to prevent import cycles
// rpc.Stop()
// return true, nil
}
func (self *adminApi) NodeInfo(req *shared.Request) (interface{}, error) {
return self.ethereum.NodeInfo(), nil
}
func hasAllBlocks(chain *core.ChainManager, bs []*types.Block) bool {
for _, b := range bs {
if !chain.HasBlock(b.Hash()) {
return false
}
}
return true
}
func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) {
args := new(ImportExportChainArgs)
if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
fh, err := os.Open(args.Filename)
if err != nil {
return false, err
}
defer fh.Close()
stream := rlp.NewStream(fh, 0)
// Run actual the import.
blocks := make(types.Blocks, importBatchSize)
n := 0
for batch := 0; ; batch++ {
i := 0
for ; i < importBatchSize; i++ {
var b types.Block
if err := stream.Decode(&b); err == io.EOF {
break
} else if err != nil {
return false, fmt.Errorf("at block %d: %v", n, err)
}
blocks[i] = &b
n++
}
if i == 0 {
break
}
// Import the batch.
if hasAllBlocks(self.ethereum.ChainManager(), blocks[:i]) {
continue
}
if _, err := self.ethereum.ChainManager().InsertChain(blocks[:i]); err != nil {
return false, fmt.Errorf("invalid block %d: %v", n, err)
}
}
return true, nil
}
func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) {
args := new(ImportExportChainArgs)
if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
fh, err := os.OpenFile(args.Filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
if err != nil {
return false, err
}
defer fh.Close()
if err := self.ethereum.ChainManager().Export(fh); err != nil {
return false, err
}
return true, nil
}
func (self *adminApi) Verbosity(req *shared.Request) (interface{}, error) {
args := new(VerbosityArgs)
if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
glog.SetV(args.Level)
return true, nil
}
func (self *adminApi) SyncStatus(req *shared.Request) (interface{}, error) {
pending, cached := self.ethereum.Downloader().Stats()
return map[string]interface{}{"available": pending, "waitingForImport": cached}, nil
}
func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) {
args := new(SetSolcArgs)
if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
solc, err := self.xeth.SetSolc(args.Path)
if err != nil {
return nil, err
}
return solc.Info(), nil
}

107
rpc/api/admin_args.go Normal file
View File

@ -0,0 +1,107 @@
package api
import (
"encoding/json"
"math/big"
"github.com/ethereum/go-ethereum/rpc/shared"
)
type AddPeerArgs struct {
Url string
}
func (args *AddPeerArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) != 1 {
return shared.NewDecodeParamError("Expected enode as argument")
}
urlstr, ok := obj[0].(string)
if !ok {
return shared.NewInvalidTypeError("url", "not a string")
}
args.Url = urlstr
return nil
}
type ImportExportChainArgs struct {
Filename string
}
func (args *ImportExportChainArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) != 1 {
return shared.NewDecodeParamError("Expected filename as argument")
}
filename, ok := obj[0].(string)
if !ok {
return shared.NewInvalidTypeError("filename", "not a string")
}
args.Filename = filename
return nil
}
type VerbosityArgs struct {
Level int
}
func (args *VerbosityArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) != 1 {
return shared.NewDecodeParamError("Expected enode as argument")
}
if levelint, ok := obj[0].(int); ok {
args.Level = levelint
} else if levelstr, ok := obj[0].(string); ok {
if !ok {
return shared.NewInvalidTypeError("level", "not a string")
}
level, success := new(big.Int).SetString(levelstr, 0)
if !success {
return shared.NewDecodeParamError("Unable to parse verbosity level")
}
args.Level = int(level.Int64())
}
return nil
}
type SetSolcArgs struct {
Path string
}
func (args *SetSolcArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) != 1 {
return shared.NewDecodeParamError("Expected path as argument")
}
if pathstr, ok := obj[0].(string); ok {
args.Path = pathstr
return nil
}
return shared.NewInvalidTypeError("path", "not a string")
}

67
rpc/api/admin_js.go Normal file
View File

@ -0,0 +1,67 @@
package api
const Admin_JS = `
web3.extend({
property: 'admin',
methods:
[
new web3.extend.Method({
name: 'addPeer',
call: 'admin_addPeer',
params: 1,
inputFormatter: [web3.extend.utils.formatInputString],
outputFormatter: web3.extend.formatters.formatOutputBool
}),
new web3.extend.Method({
name: 'peers',
call: 'admin_peers',
params: 0,
inputFormatter: [],
outputFormatter: function(obj) { return obj; }
}),
new web3.extend.Method({
name: 'exportChain',
call: 'admin_exportChain',
params: 1,
inputFormatter: [web3.extend.utils.formatInputString],
outputFormatter: function(obj) { return obj; }
}),
new web3.extend.Method({
name: 'importChain',
call: 'admin_importChain',
params: 1,
inputFormatter: [web3.extend.utils.formatInputString],
outputFormatter: function(obj) { return obj; }
}),
new web3.extend.Method({
name: 'verbosity',
call: 'admin_verbosity',
params: 1,
inputFormatter: [web3.extend.utils.formatInputInt],
outputFormatter: web3.extend.formatters.formatOutputBool
}),
new web3.extend.Method({
name: 'syncStatus',
call: 'admin_syncStatus',
params: 1,
inputFormatter: [web3.extend.utils.formatInputInt],
outputFormatter: function(obj) { return obj; }
}),
new web3.extend.Method({
name: 'setSolc',
call: 'admin_setSolc',
params: 1,
inputFormatter: [web3.extend.utils.formatInputString],
outputFormatter: web3.extend.formatters.formatOutputString
})
],
properties:
[
new web3.extend.Property({
name: 'nodeInfo',
getter: 'admin_nodeInfo',
outputFormatter: web3.extend.formatters.formatOutputString
})
]
});
`

View File

@ -7,6 +7,7 @@ import (
) )
const ( const (
AdminApiName = "admin"
EthApiName = "eth" EthApiName = "eth"
DebugApiName = "debug" DebugApiName = "debug"
MergedApiName = "merged" MergedApiName = "merged"
@ -19,11 +20,7 @@ const (
var ( var (
// List with all API's which are offered over the IPC interface by default // List with all API's which are offered over the IPC interface by default
DefaultIpcApis = strings.Join([]string{ DefaultIpcApis = strings.Join([]string{
EthApiName, AdminApiName, EthApiName, DebugApiName, MinerApiName, NetApiName, PersonalApiName, Web3ApiName,
DebugApiName,
MinerApiName,
NetApiName,
PersonalApiName,
}, ",") }, ",")
) )

View File

@ -20,20 +20,20 @@ const (
var ( var (
// mapping between methods and handlers // mapping between methods and handlers
DebugMapping = map[string]debughandler{ DebugMapping = map[string]debughandler{
"debug_dumpBlock": (*DebugApi).DumpBlock, "debug_dumpBlock": (*debugApi).DumpBlock,
"debug_getBlockRlp": (*DebugApi).GetBlockRlp, "debug_getBlockRlp": (*debugApi).GetBlockRlp,
"debug_printBlock": (*DebugApi).PrintBlock, "debug_printBlock": (*debugApi).PrintBlock,
"debug_processBlock": (*DebugApi).ProcessBlock, "debug_processBlock": (*debugApi).ProcessBlock,
"debug_seedHash": (*DebugApi).SeedHash, "debug_seedHash": (*debugApi).SeedHash,
"debug_setHead": (*DebugApi).SetHead, "debug_setHead": (*debugApi).SetHead,
} }
) )
// debug callback handler // debug callback handler
type debughandler func(*DebugApi, *shared.Request) (interface{}, error) type debughandler func(*debugApi, *shared.Request) (interface{}, error)
// admin api provider // admin api provider
type DebugApi struct { type debugApi struct {
xeth *xeth.XEth xeth *xeth.XEth
ethereum *eth.Ethereum ethereum *eth.Ethereum
methods map[string]debughandler methods map[string]debughandler
@ -41,8 +41,8 @@ type DebugApi struct {
} }
// create a new debug api instance // create a new debug api instance
func NewDebugApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *DebugApi { func NewDebugApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *debugApi {
return &DebugApi{ return &debugApi{
xeth: xeth, xeth: xeth,
ethereum: ethereum, ethereum: ethereum,
methods: DebugMapping, methods: DebugMapping,
@ -51,7 +51,7 @@ func NewDebugApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *De
} }
// collection with supported methods // collection with supported methods
func (self *DebugApi) Methods() []string { func (self *debugApi) Methods() []string {
methods := make([]string, len(self.methods)) methods := make([]string, len(self.methods))
i := 0 i := 0
for k := range self.methods { for k := range self.methods {
@ -62,7 +62,7 @@ func (self *DebugApi) Methods() []string {
} }
// Execute given request // Execute given request
func (self *DebugApi) Execute(req *shared.Request) (interface{}, error) { func (self *debugApi) Execute(req *shared.Request) (interface{}, error) {
if callback, ok := self.methods[req.Method]; ok { if callback, ok := self.methods[req.Method]; ok {
return callback(self, req) return callback(self, req)
} }
@ -70,11 +70,11 @@ func (self *DebugApi) Execute(req *shared.Request) (interface{}, error) {
return nil, &shared.NotImplementedError{req.Method} return nil, &shared.NotImplementedError{req.Method}
} }
func (self *DebugApi) Name() string { func (self *debugApi) Name() string {
return DebugApiName return DebugApiName
} }
func (self *DebugApi) PrintBlock(req *shared.Request) (interface{}, error) { func (self *debugApi) PrintBlock(req *shared.Request) (interface{}, error) {
args := new(BlockNumArg) args := new(BlockNumArg)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -84,7 +84,7 @@ func (self *DebugApi) PrintBlock(req *shared.Request) (interface{}, error) {
return fmt.Sprintf("%s", block), nil return fmt.Sprintf("%s", block), nil
} }
func (self *DebugApi) DumpBlock(req *shared.Request) (interface{}, error) { func (self *debugApi) DumpBlock(req *shared.Request) (interface{}, error) {
args := new(BlockNumArg) args := new(BlockNumArg)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -103,7 +103,7 @@ func (self *DebugApi) DumpBlock(req *shared.Request) (interface{}, error) {
return stateDb.Dump(), nil return stateDb.Dump(), nil
} }
func (self *DebugApi) GetBlockRlp(req *shared.Request) (interface{}, error) { func (self *debugApi) GetBlockRlp(req *shared.Request) (interface{}, error) {
args := new(BlockNumArg) args := new(BlockNumArg)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -117,7 +117,7 @@ func (self *DebugApi) GetBlockRlp(req *shared.Request) (interface{}, error) {
return fmt.Sprintf("%x", encoded), err return fmt.Sprintf("%x", encoded), err
} }
func (self *DebugApi) SetHead(req *shared.Request) (interface{}, error) { func (self *debugApi) SetHead(req *shared.Request) (interface{}, error) {
args := new(BlockNumArg) args := new(BlockNumArg)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -133,7 +133,7 @@ func (self *DebugApi) SetHead(req *shared.Request) (interface{}, error) {
return nil, nil return nil, nil
} }
func (self *DebugApi) ProcessBlock(req *shared.Request) (interface{}, error) { func (self *debugApi) ProcessBlock(req *shared.Request) (interface{}, error) {
args := new(BlockNumArg) args := new(BlockNumArg)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -155,7 +155,7 @@ func (self *DebugApi) ProcessBlock(req *shared.Request) (interface{}, error) {
return false, err return false, err
} }
func (self *DebugApi) SeedHash(req *shared.Request) (interface{}, error) { func (self *debugApi) SeedHash(req *shared.Request) (interface{}, error) {
args := new(BlockNumArg) args := new(BlockNumArg)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())

View File

@ -13,68 +13,68 @@ import (
// eth api provider // eth api provider
// See https://github.com/ethereum/wiki/wiki/JSON-RPC // See https://github.com/ethereum/wiki/wiki/JSON-RPC
type EthApi struct { type ethApi struct {
xeth *xeth.XEth xeth *xeth.XEth
methods map[string]ethhandler methods map[string]ethhandler
codec codec.ApiCoder codec codec.ApiCoder
} }
// eth callback handler // eth callback handler
type ethhandler func(*EthApi, *shared.Request) (interface{}, error) type ethhandler func(*ethApi, *shared.Request) (interface{}, error)
var ( var (
ethMapping = map[string]ethhandler{ ethMapping = map[string]ethhandler{
"eth_accounts": (*EthApi).Accounts, "eth_accounts": (*ethApi).Accounts,
"eth_blockNumber": (*EthApi).BlockNumber, "eth_blockNumber": (*ethApi).BlockNumber,
"eth_getBalance": (*EthApi).GetBalance, "eth_getBalance": (*ethApi).GetBalance,
"eth_protocolVersion": (*EthApi).ProtocolVersion, "eth_protocolVersion": (*ethApi).ProtocolVersion,
"eth_coinbase": (*EthApi).Coinbase, "eth_coinbase": (*ethApi).Coinbase,
"eth_mining": (*EthApi).IsMining, "eth_mining": (*ethApi).IsMining,
"eth_gasPrice": (*EthApi).GasPrice, "eth_gasPrice": (*ethApi).GasPrice,
"eth_getStorage": (*EthApi).GetStorage, "eth_getStorage": (*ethApi).GetStorage,
"eth_storageAt": (*EthApi).GetStorage, "eth_storageAt": (*ethApi).GetStorage,
"eth_getStorageAt": (*EthApi).GetStorageAt, "eth_getStorageAt": (*ethApi).GetStorageAt,
"eth_getTransactionCount": (*EthApi).GetTransactionCount, "eth_getTransactionCount": (*ethApi).GetTransactionCount,
"eth_getBlockTransactionCountByHash": (*EthApi).GetBlockTransactionCountByHash, "eth_getBlockTransactionCountByHash": (*ethApi).GetBlockTransactionCountByHash,
"eth_getBlockTransactionCountByNumber": (*EthApi).GetBlockTransactionCountByNumber, "eth_getBlockTransactionCountByNumber": (*ethApi).GetBlockTransactionCountByNumber,
"eth_getUncleCountByBlockHash": (*EthApi).GetUncleCountByBlockHash, "eth_getUncleCountByBlockHash": (*ethApi).GetUncleCountByBlockHash,
"eth_getUncleCountByBlockNumber": (*EthApi).GetUncleCountByBlockNumber, "eth_getUncleCountByBlockNumber": (*ethApi).GetUncleCountByBlockNumber,
"eth_getData": (*EthApi).GetData, "eth_getData": (*ethApi).GetData,
"eth_getCode": (*EthApi).GetData, "eth_getCode": (*ethApi).GetData,
"eth_sign": (*EthApi).Sign, "eth_sign": (*ethApi).Sign,
"eth_sendTransaction": (*EthApi).SendTransaction, "eth_sendTransaction": (*ethApi).SendTransaction,
"eth_transact": (*EthApi).SendTransaction, "eth_transact": (*ethApi).SendTransaction,
"eth_estimateGas": (*EthApi).EstimateGas, "eth_estimateGas": (*ethApi).EstimateGas,
"eth_call": (*EthApi).Call, "eth_call": (*ethApi).Call,
"eth_flush": (*EthApi).Flush, "eth_flush": (*ethApi).Flush,
"eth_getBlockByHash": (*EthApi).GetBlockByHash, "eth_getBlockByHash": (*ethApi).GetBlockByHash,
"eth_getBlockByNumber": (*EthApi).GetBlockByNumber, "eth_getBlockByNumber": (*ethApi).GetBlockByNumber,
"eth_getTransactionByHash": (*EthApi).GetTransactionByHash, "eth_getTransactionByHash": (*ethApi).GetTransactionByHash,
"eth_getTransactionByBlockHashAndIndex": (*EthApi).GetTransactionByBlockHashAndIndex, "eth_getTransactionByBlockHashAndIndex": (*ethApi).GetTransactionByBlockHashAndIndex,
"eth_getUncleByBlockHashAndIndex": (*EthApi).GetUncleByBlockHashAndIndex, "eth_getUncleByBlockHashAndIndex": (*ethApi).GetUncleByBlockHashAndIndex,
"eth_getUncleByBlockNumberAndIndex": (*EthApi).GetUncleByBlockNumberAndIndex, "eth_getUncleByBlockNumberAndIndex": (*ethApi).GetUncleByBlockNumberAndIndex,
"eth_getCompilers": (*EthApi).GetCompilers, "eth_getCompilers": (*ethApi).GetCompilers,
"eth_compileSolidity": (*EthApi).CompileSolidity, "eth_compileSolidity": (*ethApi).CompileSolidity,
"eth_newFilter": (*EthApi).NewFilter, "eth_newFilter": (*ethApi).NewFilter,
"eth_newBlockFilter": (*EthApi).NewBlockFilter, "eth_newBlockFilter": (*ethApi).NewBlockFilter,
"eth_newPendingTransactionFilter": (*EthApi).NewPendingTransactionFilter, "eth_newPendingTransactionFilter": (*ethApi).NewPendingTransactionFilter,
"eth_uninstallFilter": (*EthApi).UninstallFilter, "eth_uninstallFilter": (*ethApi).UninstallFilter,
"eth_getFilterChanges": (*EthApi).GetFilterChanges, "eth_getFilterChanges": (*ethApi).GetFilterChanges,
"eth_getFilterLogs": (*EthApi).GetFilterLogs, "eth_getFilterLogs": (*ethApi).GetFilterLogs,
"eth_getLogs": (*EthApi).GetLogs, "eth_getLogs": (*ethApi).GetLogs,
"eth_hashrate": (*EthApi).Hashrate, "eth_hashrate": (*ethApi).Hashrate,
"eth_getWork": (*EthApi).GetWork, "eth_getWork": (*ethApi).GetWork,
"eth_submitWork": (*EthApi).SubmitWork, "eth_submitWork": (*ethApi).SubmitWork,
} }
) )
// create new EthApi instance // create new ethApi instance
func NewEthApi(xeth *xeth.XEth, codec codec.Codec) *EthApi { func NewEthApi(xeth *xeth.XEth, codec codec.Codec) *ethApi {
return &EthApi{xeth, ethMapping, codec.New(nil)} return &ethApi{xeth, ethMapping, codec.New(nil)}
} }
// collection with supported methods // collection with supported methods
func (self *EthApi) Methods() []string { func (self *ethApi) Methods() []string {
methods := make([]string, len(self.methods)) methods := make([]string, len(self.methods))
i := 0 i := 0
for k := range self.methods { for k := range self.methods {
@ -85,7 +85,7 @@ func (self *EthApi) Methods() []string {
} }
// Execute given request // Execute given request
func (self *EthApi) Execute(req *shared.Request) (interface{}, error) { func (self *ethApi) Execute(req *shared.Request) (interface{}, error) {
if callback, ok := self.methods[req.Method]; ok { if callback, ok := self.methods[req.Method]; ok {
return callback(self, req) return callback(self, req)
} }
@ -93,23 +93,23 @@ func (self *EthApi) Execute(req *shared.Request) (interface{}, error) {
return nil, shared.NewNotImplementedError(req.Method) return nil, shared.NewNotImplementedError(req.Method)
} }
func (self *EthApi) Name() string { func (self *ethApi) Name() string {
return EthApiName return EthApiName
} }
func (self *EthApi) Accounts(req *shared.Request) (interface{}, error) { func (self *ethApi) Accounts(req *shared.Request) (interface{}, error) {
return self.xeth.Accounts(), nil return self.xeth.Accounts(), nil
} }
func (self *EthApi) Hashrate(req *shared.Request) (interface{}, error) { func (self *ethApi) Hashrate(req *shared.Request) (interface{}, error) {
return newHexNum(self.xeth.HashRate()), nil return newHexNum(self.xeth.HashRate()), nil
} }
func (self *EthApi) BlockNumber(req *shared.Request) (interface{}, error) { func (self *ethApi) BlockNumber(req *shared.Request) (interface{}, error) {
return self.xeth.CurrentBlock().Number(), nil return self.xeth.CurrentBlock().Number(), nil
} }
func (self *EthApi) GetBalance(req *shared.Request) (interface{}, error) { func (self *ethApi) GetBalance(req *shared.Request) (interface{}, error) {
args := new(GetBalanceArgs) args := new(GetBalanceArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -118,23 +118,23 @@ func (self *EthApi) GetBalance(req *shared.Request) (interface{}, error) {
return self.xeth.AtStateNum(args.BlockNumber).BalanceAt(args.Address), nil return self.xeth.AtStateNum(args.BlockNumber).BalanceAt(args.Address), nil
} }
func (self *EthApi) ProtocolVersion(req *shared.Request) (interface{}, error) { func (self *ethApi) ProtocolVersion(req *shared.Request) (interface{}, error) {
return self.xeth.EthVersion(), nil return self.xeth.EthVersion(), nil
} }
func (self *EthApi) Coinbase(req *shared.Request) (interface{}, error) { func (self *ethApi) Coinbase(req *shared.Request) (interface{}, error) {
return newHexData(self.xeth.Coinbase()), nil return newHexData(self.xeth.Coinbase()), nil
} }
func (self *EthApi) IsMining(req *shared.Request) (interface{}, error) { func (self *ethApi) IsMining(req *shared.Request) (interface{}, error) {
return self.xeth.IsMining(), nil return self.xeth.IsMining(), nil
} }
func (self *EthApi) GasPrice(req *shared.Request) (interface{}, error) { func (self *ethApi) GasPrice(req *shared.Request) (interface{}, error) {
return newHexNum(xeth.DefaultGasPrice().Bytes()), nil return newHexNum(xeth.DefaultGasPrice().Bytes()), nil
} }
func (self *EthApi) GetStorage(req *shared.Request) (interface{}, error) { func (self *ethApi) GetStorage(req *shared.Request) (interface{}, error) {
args := new(GetStorageArgs) args := new(GetStorageArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -143,7 +143,7 @@ func (self *EthApi) GetStorage(req *shared.Request) (interface{}, error) {
return self.xeth.AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage(), nil return self.xeth.AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage(), nil
} }
func (self *EthApi) GetStorageAt(req *shared.Request) (interface{}, error) { func (self *ethApi) GetStorageAt(req *shared.Request) (interface{}, error) {
args := new(GetStorageAtArgs) args := new(GetStorageAtArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -152,7 +152,7 @@ func (self *EthApi) GetStorageAt(req *shared.Request) (interface{}, error) {
return self.xeth.AtStateNum(args.BlockNumber).StorageAt(args.Address, args.Key), nil return self.xeth.AtStateNum(args.BlockNumber).StorageAt(args.Address, args.Key), nil
} }
func (self *EthApi) GetTransactionCount(req *shared.Request) (interface{}, error) { func (self *ethApi) GetTransactionCount(req *shared.Request) (interface{}, error) {
args := new(GetTxCountArgs) args := new(GetTxCountArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -162,7 +162,7 @@ func (self *EthApi) GetTransactionCount(req *shared.Request) (interface{}, error
return newHexNum(big.NewInt(int64(count)).Bytes()), nil return newHexNum(big.NewInt(int64(count)).Bytes()), nil
} }
func (self *EthApi) GetBlockTransactionCountByHash(req *shared.Request) (interface{}, error) { func (self *ethApi) GetBlockTransactionCountByHash(req *shared.Request) (interface{}, error) {
args := new(HashArgs) args := new(HashArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -176,7 +176,7 @@ func (self *EthApi) GetBlockTransactionCountByHash(req *shared.Request) (interfa
} }
} }
func (self *EthApi) GetBlockTransactionCountByNumber(req *shared.Request) (interface{}, error) { func (self *ethApi) GetBlockTransactionCountByNumber(req *shared.Request) (interface{}, error) {
args := new(BlockNumArg) args := new(BlockNumArg)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -190,7 +190,7 @@ func (self *EthApi) GetBlockTransactionCountByNumber(req *shared.Request) (inter
} }
} }
func (self *EthApi) GetUncleCountByBlockHash(req *shared.Request) (interface{}, error) { func (self *ethApi) GetUncleCountByBlockHash(req *shared.Request) (interface{}, error) {
args := new(HashArgs) args := new(HashArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -204,7 +204,7 @@ func (self *EthApi) GetUncleCountByBlockHash(req *shared.Request) (interface{},
return newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()), nil return newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()), nil
} }
func (self *EthApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}, error) { func (self *ethApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}, error) {
args := new(BlockNumArg) args := new(BlockNumArg)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -218,7 +218,7 @@ func (self *EthApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}
return newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()), nil return newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()), nil
} }
func (self *EthApi) GetData(req *shared.Request) (interface{}, error) { func (self *ethApi) GetData(req *shared.Request) (interface{}, error) {
args := new(GetDataArgs) args := new(GetDataArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -227,8 +227,8 @@ func (self *EthApi) GetData(req *shared.Request) (interface{}, error) {
return newHexData(v), nil return newHexData(v), nil
} }
func (self *EthApi) Sign(req *shared.Request) (interface{}, error) { func (self *ethApi) Sign(req *shared.Request) (interface{}, error) {
args := new(NewSignArgs) args := new(NewSigArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
} }
@ -239,7 +239,7 @@ func (self *EthApi) Sign(req *shared.Request) (interface{}, error) {
return v, nil return v, nil
} }
func (self *EthApi) SendTransaction(req *shared.Request) (interface{}, error) { func (self *ethApi) SendTransaction(req *shared.Request) (interface{}, error) {
args := new(NewTxArgs) args := new(NewTxArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -258,7 +258,7 @@ func (self *EthApi) SendTransaction(req *shared.Request) (interface{}, error) {
return v, nil return v, nil
} }
func (self *EthApi) EstimateGas(req *shared.Request) (interface{}, error) { func (self *ethApi) EstimateGas(req *shared.Request) (interface{}, error) {
_, gas, err := self.doCall(req.Params) _, gas, err := self.doCall(req.Params)
if err != nil { if err != nil {
return nil, err return nil, err
@ -272,7 +272,7 @@ func (self *EthApi) EstimateGas(req *shared.Request) (interface{}, error) {
} }
} }
func (self *EthApi) Call(req *shared.Request) (interface{}, error) { func (self *ethApi) Call(req *shared.Request) (interface{}, error) {
v, _, err := self.doCall(req.Params) v, _, err := self.doCall(req.Params)
if err != nil { if err != nil {
return nil, err return nil, err
@ -286,11 +286,11 @@ func (self *EthApi) Call(req *shared.Request) (interface{}, error) {
} }
} }
func (self *EthApi) Flush(req *shared.Request) (interface{}, error) { func (self *ethApi) Flush(req *shared.Request) (interface{}, error) {
return nil, shared.NewNotImplementedError(req.Method) return nil, shared.NewNotImplementedError(req.Method)
} }
func (self *EthApi) doCall(params json.RawMessage) (string, string, error) { func (self *ethApi) doCall(params json.RawMessage) (string, string, error) {
args := new(CallArgs) args := new(CallArgs)
if err := self.codec.Decode(params, &args); err != nil { if err := self.codec.Decode(params, &args); err != nil {
return "", "", err return "", "", err
@ -299,7 +299,7 @@ func (self *EthApi) doCall(params json.RawMessage) (string, string, error) {
return self.xeth.AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) return self.xeth.AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data)
} }
func (self *EthApi) GetBlockByHash(req *shared.Request) (interface{}, error) { func (self *ethApi) GetBlockByHash(req *shared.Request) (interface{}, error) {
args := new(GetBlockByHashArgs) args := new(GetBlockByHashArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -309,7 +309,7 @@ func (self *EthApi) GetBlockByHash(req *shared.Request) (interface{}, error) {
return NewBlockRes(block, args.IncludeTxs), nil return NewBlockRes(block, args.IncludeTxs), nil
} }
func (self *EthApi) GetBlockByNumber(req *shared.Request) (interface{}, error) { func (self *ethApi) GetBlockByNumber(req *shared.Request) (interface{}, error) {
args := new(GetBlockByNumberArgs) args := new(GetBlockByNumberArgs)
if err := json.Unmarshal(req.Params, &args); err != nil { if err := json.Unmarshal(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -328,7 +328,7 @@ func (self *EthApi) GetBlockByNumber(req *shared.Request) (interface{}, error) {
return br, nil return br, nil
} }
func (self *EthApi) GetTransactionByHash(req *shared.Request) (interface{}, error) { func (self *ethApi) GetTransactionByHash(req *shared.Request) (interface{}, error) {
args := new(HashArgs) args := new(HashArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -348,7 +348,7 @@ func (self *EthApi) GetTransactionByHash(req *shared.Request) (interface{}, erro
return nil, nil return nil, nil
} }
func (self *EthApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (interface{}, error) { func (self *ethApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (interface{}, error) {
args := new(HashIndexArgs) args := new(HashIndexArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -367,7 +367,7 @@ func (self *EthApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (inte
} }
} }
func (self *EthApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (interface{}, error) { func (self *ethApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (interface{}, error) {
args := new(BlockNumIndexArgs) args := new(BlockNumIndexArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -386,7 +386,7 @@ func (self *EthApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (in
return v.Transactions[args.Index], nil return v.Transactions[args.Index], nil
} }
func (self *EthApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{}, error) { func (self *ethApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{}, error) {
args := new(HashIndexArgs) args := new(HashIndexArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -405,7 +405,7 @@ func (self *EthApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{
return br.Uncles[args.Index], nil return br.Uncles[args.Index], nil
} }
func (self *EthApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interface{}, error) { func (self *ethApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interface{}, error) {
args := new(BlockNumIndexArgs) args := new(BlockNumIndexArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -425,7 +425,7 @@ func (self *EthApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interfac
} }
} }
func (self *EthApi) GetCompilers(req *shared.Request) (interface{}, error) { func (self *ethApi) GetCompilers(req *shared.Request) (interface{}, error) {
var lang string var lang string
if solc, _ := self.xeth.Solc(); solc != nil { if solc, _ := self.xeth.Solc(); solc != nil {
lang = "Solidity" lang = "Solidity"
@ -434,7 +434,7 @@ func (self *EthApi) GetCompilers(req *shared.Request) (interface{}, error) {
return c, nil return c, nil
} }
func (self *EthApi) CompileSolidity(req *shared.Request) (interface{}, error) { func (self *ethApi) CompileSolidity(req *shared.Request) (interface{}, error) {
solc, _ := self.xeth.Solc() solc, _ := self.xeth.Solc()
if solc == nil { if solc == nil {
return nil, shared.NewNotAvailableError(req.Method, "solc (solidity compiler) not found") return nil, shared.NewNotAvailableError(req.Method, "solc (solidity compiler) not found")
@ -452,7 +452,7 @@ func (self *EthApi) CompileSolidity(req *shared.Request) (interface{}, error) {
return contracts, nil return contracts, nil
} }
func (self *EthApi) NewFilter(req *shared.Request) (interface{}, error) { func (self *ethApi) NewFilter(req *shared.Request) (interface{}, error) {
args := new(BlockFilterArgs) args := new(BlockFilterArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -462,15 +462,15 @@ func (self *EthApi) NewFilter(req *shared.Request) (interface{}, error) {
return newHexNum(big.NewInt(int64(id)).Bytes()), nil return newHexNum(big.NewInt(int64(id)).Bytes()), nil
} }
func (self *EthApi) NewBlockFilter(req *shared.Request) (interface{}, error) { func (self *ethApi) NewBlockFilter(req *shared.Request) (interface{}, error) {
return newHexNum(self.xeth.NewBlockFilter()), nil return newHexNum(self.xeth.NewBlockFilter()), nil
} }
func (self *EthApi) NewPendingTransactionFilter(req *shared.Request) (interface{}, error) { func (self *ethApi) NewPendingTransactionFilter(req *shared.Request) (interface{}, error) {
return newHexNum(self.xeth.NewTransactionFilter()), nil return newHexNum(self.xeth.NewTransactionFilter()), nil
} }
func (self *EthApi) UninstallFilter(req *shared.Request) (interface{}, error) { func (self *ethApi) UninstallFilter(req *shared.Request) (interface{}, error) {
args := new(FilterIdArgs) args := new(FilterIdArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -478,7 +478,7 @@ func (self *EthApi) UninstallFilter(req *shared.Request) (interface{}, error) {
return self.xeth.UninstallFilter(args.Id), nil return self.xeth.UninstallFilter(args.Id), nil
} }
func (self *EthApi) GetFilterChanges(req *shared.Request) (interface{}, error) { func (self *ethApi) GetFilterChanges(req *shared.Request) (interface{}, error) {
args := new(FilterIdArgs) args := new(FilterIdArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -496,7 +496,7 @@ func (self *EthApi) GetFilterChanges(req *shared.Request) (interface{}, error) {
} }
} }
func (self *EthApi) GetFilterLogs(req *shared.Request) (interface{}, error) { func (self *ethApi) GetFilterLogs(req *shared.Request) (interface{}, error) {
args := new(FilterIdArgs) args := new(FilterIdArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -505,7 +505,7 @@ func (self *EthApi) GetFilterLogs(req *shared.Request) (interface{}, error) {
return NewLogsRes(self.xeth.Logs(args.Id)), nil return NewLogsRes(self.xeth.Logs(args.Id)), nil
} }
func (self *EthApi) GetLogs(req *shared.Request) (interface{}, error) { func (self *ethApi) GetLogs(req *shared.Request) (interface{}, error) {
args := new(BlockFilterArgs) args := new(BlockFilterArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -513,12 +513,12 @@ func (self *EthApi) GetLogs(req *shared.Request) (interface{}, error) {
return NewLogsRes(self.xeth.AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)), nil return NewLogsRes(self.xeth.AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)), nil
} }
func (self *EthApi) GetWork(req *shared.Request) (interface{}, error) { func (self *ethApi) GetWork(req *shared.Request) (interface{}, error) {
self.xeth.SetMining(true, 0) self.xeth.SetMining(true, 0)
return self.xeth.RemoteMining().GetWork(), nil return self.xeth.RemoteMining().GetWork(), nil
} }
func (self *EthApi) SubmitWork(req *shared.Request) (interface{}, error) { func (self *ethApi) SubmitWork(req *shared.Request) (interface{}, error) {
args := new(SubmitWorkArgs) args := new(SubmitWorkArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())

View File

@ -226,19 +226,14 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
return nil return nil
} }
type NewSignArgs struct { type NewSigArgs struct {
From string From string
Data string Data string
} }
func (args *NewSignArgs) UnmarshalJSON(b []byte) (err error) { func (args *NewSigArgs) UnmarshalJSON(b []byte) (err error) {
var obj []json.RawMessage var obj []interface{}
var ext struct {
From string
Data string
}
// Decode byte slice to array of RawMessages
if err := json.Unmarshal(b, &obj); err != nil { if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error()) return shared.NewDecodeParamError(err.Error())
} }
@ -248,21 +243,26 @@ func (args *NewSignArgs) UnmarshalJSON(b []byte) (err error) {
return shared.NewInsufficientParamsError(len(obj), 1) return shared.NewInsufficientParamsError(len(obj), 1)
} }
// Decode 0th RawMessage to temporary struct from, ok := obj[0].(string)
if err := json.Unmarshal(obj[0], &ext); err != nil { if !ok {
return shared.NewDecodeParamError(err.Error()) return shared.NewInvalidTypeError("from", "not a string")
} }
args.From = from
if len(ext.From) == 0 { if len(args.From) == 0 {
return shared.NewValidationError("from", "is required") return shared.NewValidationError("from", "is required")
} }
if len(ext.Data) == 0 { data, ok := obj[1].(string)
if !ok {
return shared.NewInvalidTypeError("data", "not a string")
}
args.Data = data
if len(args.Data) == 0 {
return shared.NewValidationError("data", "is required") return shared.NewValidationError("data", "is required")
} }
args.From = ext.From
args.Data = ext.Data
return nil return nil
} }

View File

@ -3,14 +3,14 @@ package api
import "github.com/ethereum/go-ethereum/rpc/shared" import "github.com/ethereum/go-ethereum/rpc/shared"
// combines multiple API's // combines multiple API's
type mergedApi struct { type MergedApi struct {
apis []string apis []string
methods map[string]EthereumApi methods map[string]EthereumApi
} }
// create new merged api instance // create new merged api instance
func newMergedApi(apis ...EthereumApi) *mergedApi { func newMergedApi(apis ...EthereumApi) *MergedApi {
mergedApi := new(mergedApi) mergedApi := new(MergedApi)
mergedApi.apis = make([]string, len(apis)) mergedApi.apis = make([]string, len(apis))
mergedApi.methods = make(map[string]EthereumApi) mergedApi.methods = make(map[string]EthereumApi)
@ -24,7 +24,7 @@ func newMergedApi(apis ...EthereumApi) *mergedApi {
} }
// Supported RPC methods // Supported RPC methods
func (self *mergedApi) Methods() []string { func (self *MergedApi) Methods() []string {
all := make([]string, len(self.methods)) all := make([]string, len(self.methods))
for method, _ := range self.methods { for method, _ := range self.methods {
all = append(all, method) all = append(all, method)
@ -33,7 +33,7 @@ func (self *mergedApi) Methods() []string {
} }
// Call the correct API's Execute method for the given request // Call the correct API's Execute method for the given request
func (self *mergedApi) Execute(req *shared.Request) (interface{}, error) { func (self *MergedApi) Execute(req *shared.Request) (interface{}, error) {
if res, _ := self.handle(req); res != nil { if res, _ := self.handle(req); res != nil {
return res, nil return res, nil
} }
@ -43,11 +43,11 @@ func (self *mergedApi) Execute(req *shared.Request) (interface{}, error) {
return nil, shared.NewNotImplementedError(req.Method) return nil, shared.NewNotImplementedError(req.Method)
} }
func (self *mergedApi) Name() string { func (self *MergedApi) Name() string {
return MergedApiName return MergedApiName
} }
func (self *mergedApi) handle(req *shared.Request) (interface{}, error) { func (self *MergedApi) handle(req *shared.Request) (interface{}, error) {
if req.Method == "support_apis" { // provided API's if req.Method == "support_apis" { // provided API's
return self.apis, nil return self.apis, nil
} }

View File

@ -15,30 +15,30 @@ const (
var ( var (
// mapping between methods and handlers // mapping between methods and handlers
MinerMapping = map[string]minerhandler{ MinerMapping = map[string]minerhandler{
"miner_hashrate": (*miner).Hashrate, "miner_hashrate": (*minerApi).Hashrate,
"miner_makeDAG": (*miner).MakeDAG, "miner_makeDAG": (*minerApi).MakeDAG,
"miner_setExtra": (*miner).SetExtra, "miner_setExtra": (*minerApi).SetExtra,
"miner_setGasPrice": (*miner).SetGasPrice, "miner_setGasPrice": (*minerApi).SetGasPrice,
"miner_startAutoDAG": (*miner).StartAutoDAG, "miner_startAutoDAG": (*minerApi).StartAutoDAG,
"miner_start": (*miner).StartMiner, "miner_start": (*minerApi).StartMiner,
"miner_stopAutoDAG": (*miner).StopAutoDAG, "miner_stopAutoDAG": (*minerApi).StopAutoDAG,
"miner_stop": (*miner).StopMiner, "miner_stop": (*minerApi).StopMiner,
} }
) )
// miner callback handler // miner callback handler
type minerhandler func(*miner, *shared.Request) (interface{}, error) type minerhandler func(*minerApi, *shared.Request) (interface{}, error)
// miner api provider // miner api provider
type miner struct { type minerApi struct {
ethereum *eth.Ethereum ethereum *eth.Ethereum
methods map[string]minerhandler methods map[string]minerhandler
codec codec.ApiCoder codec codec.ApiCoder
} }
// create a new miner api instance // create a new miner api instance
func NewMinerApi(ethereum *eth.Ethereum, coder codec.Codec) *miner { func NewMinerApi(ethereum *eth.Ethereum, coder codec.Codec) *minerApi {
return &miner{ return &minerApi{
ethereum: ethereum, ethereum: ethereum,
methods: MinerMapping, methods: MinerMapping,
codec: coder.New(nil), codec: coder.New(nil),
@ -46,7 +46,7 @@ func NewMinerApi(ethereum *eth.Ethereum, coder codec.Codec) *miner {
} }
// Execute given request // Execute given request
func (self *miner) Execute(req *shared.Request) (interface{}, error) { func (self *minerApi) Execute(req *shared.Request) (interface{}, error) {
if callback, ok := self.methods[req.Method]; ok { if callback, ok := self.methods[req.Method]; ok {
return callback(self, req) return callback(self, req)
} }
@ -55,7 +55,7 @@ func (self *miner) Execute(req *shared.Request) (interface{}, error) {
} }
// collection with supported methods // collection with supported methods
func (self *miner) Methods() []string { func (self *minerApi) Methods() []string {
methods := make([]string, len(self.methods)) methods := make([]string, len(self.methods))
i := 0 i := 0
for k := range self.methods { for k := range self.methods {
@ -65,11 +65,11 @@ func (self *miner) Methods() []string {
return methods return methods
} }
func (self *miner) Name() string { func (self *minerApi) Name() string {
return MinerApiName return MinerApiName
} }
func (self *miner) StartMiner(req *shared.Request) (interface{}, error) { func (self *minerApi) StartMiner(req *shared.Request) (interface{}, error) {
args := new(StartMinerArgs) args := new(StartMinerArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, err return nil, err
@ -87,16 +87,16 @@ func (self *miner) StartMiner(req *shared.Request) (interface{}, error) {
return false, err return false, err
} }
func (self *miner) StopMiner(req *shared.Request) (interface{}, error) { func (self *minerApi) StopMiner(req *shared.Request) (interface{}, error) {
self.ethereum.StopMining() self.ethereum.StopMining()
return true, nil return true, nil
} }
func (self *miner) Hashrate(req *shared.Request) (interface{}, error) { func (self *minerApi) Hashrate(req *shared.Request) (interface{}, error) {
return self.ethereum.Miner().HashRate(), nil return self.ethereum.Miner().HashRate(), nil
} }
func (self *miner) SetExtra(req *shared.Request) (interface{}, error) { func (self *minerApi) SetExtra(req *shared.Request) (interface{}, error) {
args := new(SetExtraArgs) args := new(SetExtraArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, err return nil, err
@ -105,7 +105,7 @@ func (self *miner) SetExtra(req *shared.Request) (interface{}, error) {
return true, nil return true, nil
} }
func (self *miner) SetGasPrice(req *shared.Request) (interface{}, error) { func (self *minerApi) SetGasPrice(req *shared.Request) (interface{}, error) {
args := new(GasPriceArgs) args := new(GasPriceArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return false, err return false, err
@ -115,17 +115,17 @@ func (self *miner) SetGasPrice(req *shared.Request) (interface{}, error) {
return true, nil return true, nil
} }
func (self *miner) StartAutoDAG(req *shared.Request) (interface{}, error) { func (self *minerApi) StartAutoDAG(req *shared.Request) (interface{}, error) {
self.ethereum.StartAutoDAG() self.ethereum.StartAutoDAG()
return true, nil return true, nil
} }
func (self *miner) StopAutoDAG(req *shared.Request) (interface{}, error) { func (self *minerApi) StopAutoDAG(req *shared.Request) (interface{}, error) {
self.ethereum.StopAutoDAG() self.ethereum.StopAutoDAG()
return true, nil return true, nil
} }
func (self *miner) MakeDAG(req *shared.Request) (interface{}, error) { func (self *minerApi) MakeDAG(req *shared.Request) (interface{}, error) {
args := new(MakeDAGArgs) args := new(MakeDAGArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, err return nil, err

View File

@ -10,18 +10,18 @@ import (
var ( var (
// mapping between methods and handlers // mapping between methods and handlers
netMapping = map[string]nethandler{ netMapping = map[string]nethandler{
"net_id": (*net).NetworkVersion, "net_id": (*netApi).NetworkVersion,
"net_peerCount": (*net).PeerCount, "net_peerCount": (*netApi).PeerCount,
"net_listening": (*net).IsListening, "net_listening": (*netApi).IsListening,
"net_peers": (*net).Peers, "net_peers": (*netApi).Peers,
} }
) )
// net callback handler // net callback handler
type nethandler func(*net, *shared.Request) (interface{}, error) type nethandler func(*netApi, *shared.Request) (interface{}, error)
// net api provider // net api provider
type net struct { type netApi struct {
xeth *xeth.XEth xeth *xeth.XEth
ethereum *eth.Ethereum ethereum *eth.Ethereum
methods map[string]nethandler methods map[string]nethandler
@ -29,8 +29,8 @@ type net struct {
} }
// create a new net api instance // create a new net api instance
func NewNetApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *net { func NewNetApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *netApi {
return &net{ return &netApi{
xeth: xeth, xeth: xeth,
ethereum: eth, ethereum: eth,
methods: netMapping, methods: netMapping,
@ -39,7 +39,7 @@ func NewNetApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *net {
} }
// collection with supported methods // collection with supported methods
func (self *net) Methods() []string { func (self *netApi) Methods() []string {
methods := make([]string, len(self.methods)) methods := make([]string, len(self.methods))
i := 0 i := 0
for k := range self.methods { for k := range self.methods {
@ -50,7 +50,7 @@ func (self *net) Methods() []string {
} }
// Execute given request // Execute given request
func (self *net) Execute(req *shared.Request) (interface{}, error) { func (self *netApi) Execute(req *shared.Request) (interface{}, error) {
if callback, ok := self.methods[req.Method]; ok { if callback, ok := self.methods[req.Method]; ok {
return callback(self, req) return callback(self, req)
} }
@ -58,24 +58,24 @@ func (self *net) Execute(req *shared.Request) (interface{}, error) {
return nil, shared.NewNotImplementedError(req.Method) return nil, shared.NewNotImplementedError(req.Method)
} }
func (self *net) Name() string { func (self *netApi) Name() string {
return NetApiName return NetApiName
} }
// Network version // Network version
func (self *net) NetworkVersion(req *shared.Request) (interface{}, error) { func (self *netApi) NetworkVersion(req *shared.Request) (interface{}, error) {
return self.xeth.NetworkVersion(), nil return self.xeth.NetworkVersion(), nil
} }
// Number of connected peers // Number of connected peers
func (self *net) PeerCount(req *shared.Request) (interface{}, error) { func (self *netApi) PeerCount(req *shared.Request) (interface{}, error) {
return self.xeth.PeerCount(), nil return self.xeth.PeerCount(), nil
} }
func (self *net) IsListening(req *shared.Request) (interface{}, error) { func (self *netApi) IsListening(req *shared.Request) (interface{}, error) {
return self.xeth.IsListening(), nil return self.xeth.IsListening(), nil
} }
func (self *net) Peers(req *shared.Request) (interface{}, error) { func (self *netApi) Peers(req *shared.Request) (interface{}, error) {
return self.ethereum.PeersInfo(), nil return self.ethereum.PeersInfo(), nil
} }

View File

@ -5,6 +5,13 @@ web3.extend({
property: 'network', property: 'network',
methods: methods:
[ [
new web3.extend.Method({
name: 'addPeer',
call: 'net_addPeer',
params: 1,
inputFormatter: [web3.extend.utils.formatInputString],
outputFormatter: web3.extend.formatters.formatOutputBool
}),
new web3.extend.Method({ new web3.extend.Method({
name: 'id', name: 'id',
call: 'net_id', call: 'net_id',

View File

@ -13,18 +13,18 @@ import (
var ( var (
// mapping between methods and handlers // mapping between methods and handlers
personalMapping = map[string]personalhandler{ personalMapping = map[string]personalhandler{
"personal_listAccounts": (*personal).ListAccounts, "personal_listAccounts": (*personalApi).ListAccounts,
"personal_newAccount": (*personal).NewAccount, "personal_newAccount": (*personalApi).NewAccount,
"personal_deleteAccount": (*personal).DeleteAccount, "personal_deleteAccount": (*personalApi).DeleteAccount,
"personal_unlockAccount": (*personal).UnlockAccount, "personal_unlockAccount": (*personalApi).UnlockAccount,
} }
) )
// net callback handler // net callback handler
type personalhandler func(*personal, *shared.Request) (interface{}, error) type personalhandler func(*personalApi, *shared.Request) (interface{}, error)
// net api provider // net api provider
type personal struct { type personalApi struct {
xeth *xeth.XEth xeth *xeth.XEth
ethereum *eth.Ethereum ethereum *eth.Ethereum
methods map[string]personalhandler methods map[string]personalhandler
@ -32,8 +32,8 @@ type personal struct {
} }
// create a new net api instance // create a new net api instance
func NewPersonal(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *personal { func NewPersonalApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *personalApi {
return &personal{ return &personalApi{
xeth: xeth, xeth: xeth,
ethereum: eth, ethereum: eth,
methods: personalMapping, methods: personalMapping,
@ -42,7 +42,7 @@ func NewPersonal(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *persona
} }
// collection with supported methods // collection with supported methods
func (self *personal) Methods() []string { func (self *personalApi) Methods() []string {
methods := make([]string, len(self.methods)) methods := make([]string, len(self.methods))
i := 0 i := 0
for k := range self.methods { for k := range self.methods {
@ -53,7 +53,7 @@ func (self *personal) Methods() []string {
} }
// Execute given request // Execute given request
func (self *personal) Execute(req *shared.Request) (interface{}, error) { func (self *personalApi) Execute(req *shared.Request) (interface{}, error) {
if callback, ok := self.methods[req.Method]; ok { if callback, ok := self.methods[req.Method]; ok {
return callback(self, req) return callback(self, req)
} }
@ -61,15 +61,15 @@ func (self *personal) Execute(req *shared.Request) (interface{}, error) {
return nil, shared.NewNotImplementedError(req.Method) return nil, shared.NewNotImplementedError(req.Method)
} }
func (self *personal) Name() string { func (self *personalApi) Name() string {
return PersonalApiName return PersonalApiName
} }
func (self *personal) ListAccounts(req *shared.Request) (interface{}, error) { func (self *personalApi) ListAccounts(req *shared.Request) (interface{}, error) {
return self.xeth.Accounts(), nil return self.xeth.Accounts(), nil
} }
func (self *personal) NewAccount(req *shared.Request) (interface{}, error) { func (self *personalApi) NewAccount(req *shared.Request) (interface{}, error) {
args := new(NewAccountArgs) args := new(NewAccountArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -80,7 +80,7 @@ func (self *personal) NewAccount(req *shared.Request) (interface{}, error) {
return acc.Address.Hex(), err return acc.Address.Hex(), err
} }
func (self *personal) DeleteAccount(req *shared.Request) (interface{}, error) { func (self *personalApi) DeleteAccount(req *shared.Request) (interface{}, error) {
args := new(DeleteAccountArgs) args := new(DeleteAccountArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())
@ -95,7 +95,7 @@ func (self *personal) DeleteAccount(req *shared.Request) (interface{}, error) {
} }
} }
func (self *personal) UnlockAccount(req *shared.Request) (interface{}, error) { func (self *personalApi) UnlockAccount(req *shared.Request) (interface{}, error) {
args := new(UnlockAccountArgs) args := new(UnlockAccountArgs)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error()) return nil, shared.NewDecodeParamError(err.Error())

View File

@ -21,6 +21,8 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
for i, name := range names { for i, name := range names {
switch strings.ToLower(strings.TrimSpace(name)) { switch strings.ToLower(strings.TrimSpace(name)) {
case AdminApiName:
apis[i] = NewAdminApi(xeth, eth, codec)
case DebugApiName: case DebugApiName:
apis[i] = NewDebugApi(xeth, eth, codec) apis[i] = NewDebugApi(xeth, eth, codec)
case EthApiName: case EthApiName:
@ -30,9 +32,9 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
case NetApiName: case NetApiName:
apis[i] = NewNetApi(xeth, eth, codec) apis[i] = NewNetApi(xeth, eth, codec)
case PersonalApiName: case PersonalApiName:
apis[i] = NewPersonal(xeth, eth, codec) apis[i] = NewPersonalApi(xeth, eth, codec)
case Web3ApiName: case Web3ApiName:
apis[i] = NewWeb3(xeth, codec) apis[i] = NewWeb3Api(xeth, codec)
default: default:
return nil, fmt.Errorf("Unknown API '%s'", name) return nil, fmt.Errorf("Unknown API '%s'", name)
} }
@ -43,6 +45,8 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
func Javascript(name string) string { func Javascript(name string) string {
switch strings.ToLower(strings.TrimSpace(name)) { switch strings.ToLower(strings.TrimSpace(name)) {
case AdminApiName:
return Admin_JS
case DebugApiName: case DebugApiName:
return Debug_JS return Debug_JS
case MinerApiName: case MinerApiName:

View File

@ -15,24 +15,24 @@ const (
var ( var (
// mapping between methods and handlers // mapping between methods and handlers
Web3Mapping = map[string]web3handler{ Web3Mapping = map[string]web3handler{
"web3_sha3": (*web3).Sha3, "web3_sha3": (*web3Api).Sha3,
"web3_clientVersion": (*web3).ClientVersion, "web3_clientVersion": (*web3Api).ClientVersion,
} }
) )
// web3 callback handler // web3 callback handler
type web3handler func(*web3, *shared.Request) (interface{}, error) type web3handler func(*web3Api, *shared.Request) (interface{}, error)
// web3 api provider // web3 api provider
type web3 struct { type web3Api struct {
xeth *xeth.XEth xeth *xeth.XEth
methods map[string]web3handler methods map[string]web3handler
codec codec.ApiCoder codec codec.ApiCoder
} }
// create a new web3 api instance // create a new web3 api instance
func NewWeb3(xeth *xeth.XEth, coder codec.Codec) *web3 { func NewWeb3Api(xeth *xeth.XEth, coder codec.Codec) *web3Api {
return &web3{ return &web3Api{
xeth: xeth, xeth: xeth,
methods: Web3Mapping, methods: Web3Mapping,
codec: coder.New(nil), codec: coder.New(nil),
@ -40,7 +40,7 @@ func NewWeb3(xeth *xeth.XEth, coder codec.Codec) *web3 {
} }
// collection with supported methods // collection with supported methods
func (self *web3) Methods() []string { func (self *web3Api) Methods() []string {
methods := make([]string, len(self.methods)) methods := make([]string, len(self.methods))
i := 0 i := 0
for k := range self.methods { for k := range self.methods {
@ -51,7 +51,7 @@ func (self *web3) Methods() []string {
} }
// Execute given request // Execute given request
func (self *web3) Execute(req *shared.Request) (interface{}, error) { func (self *web3Api) Execute(req *shared.Request) (interface{}, error) {
if callback, ok := self.methods[req.Method]; ok { if callback, ok := self.methods[req.Method]; ok {
return callback(self, req) return callback(self, req)
} }
@ -59,17 +59,17 @@ func (self *web3) Execute(req *shared.Request) (interface{}, error) {
return nil, &shared.NotImplementedError{req.Method} return nil, &shared.NotImplementedError{req.Method}
} }
func (self *web3) Name() string { func (self *web3Api) Name() string {
return Web3ApiName return Web3ApiName
} }
// Version of the API this instance provides // Version of the API this instance provides
func (self *web3) Version() string { func (self *web3Api) Version() string {
return Web3Version return Web3Version
} }
// Calculates the sha3 over req.Params.Data // Calculates the sha3 over req.Params.Data
func (self *web3) Sha3(req *shared.Request) (interface{}, error) { func (self *web3Api) Sha3(req *shared.Request) (interface{}, error) {
args := new(Sha3Args) args := new(Sha3Args)
if err := self.codec.Decode(req.Params, &args); err != nil { if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, err return nil, err
@ -79,6 +79,6 @@ func (self *web3) Sha3(req *shared.Request) (interface{}, error) {
} }
// returns the xeth client vrsion // returns the xeth client vrsion
func (self *web3) ClientVersion(req *shared.Request) (interface{}, error) { func (self *web3Api) ClientVersion(req *shared.Request) (interface{}, error) {
return self.xeth.ClientVersion(), nil return self.xeth.ClientVersion(), nil
} }