From a11f1d6a7ec2eaa1a348776072c49019368a5ef3 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 9 Mar 2015 23:00:27 +0100 Subject: rpc: add dataDir parameter and JSON-RPC handler --- cmd/ethereum/main.go | 4 +--- cmd/utils/cmd.go | 12 ------------ cmd/utils/flags.go | 18 ++++++++++++++++++ rpc/api.go | 5 +++-- rpc/http.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 rpc/http.go diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index f5215c587..4855a3e4a 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -170,9 +170,7 @@ func runjs(ctx *cli.Context) { func startEth(ctx *cli.Context, eth *eth.Ethereum) { utils.StartEthereum(eth) if ctx.GlobalBool(utils.RPCEnabledFlag.Name) { - addr := ctx.GlobalString(utils.RPCListenAddrFlag.Name) - port := ctx.GlobalInt(utils.RPCPortFlag.Name) - utils.StartRpc(eth, addr, port) + utils.StartRPC(eth, ctx) } if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { eth.Miner().Start() diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 3c3d3955d..79ae7888a 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -34,9 +34,7 @@ import ( "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/rlp" - rpchttp "github.com/ethereum/go-ethereum/rpc/http" "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/xeth" ) var clilogger = logger.NewLogger("CLI") @@ -165,16 +163,6 @@ func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, Secre clilogger.Infof("Main address %x\n", keyManager.Address()) } -func StartRpc(ethereum *eth.Ethereum, RpcListenAddress string, RpcPort int) { - var err error - ethereum.RpcServer, err = rpchttp.NewRpcHttpServer(xeth.New(ethereum), RpcListenAddress, RpcPort) - if err != nil { - clilogger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err) - } else { - go ethereum.RpcServer.Start() - } -} - func FormatTransactionData(data string) []byte { d := ethutil.StringToByteFunc(data, func(s string) (ret []byte) { slice := regexp.MustCompile("\\n|\\s").Split(s, 1000000000) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 2156963c4..2995ebad8 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2,6 +2,10 @@ package utils import ( "crypto/ecdsa" + "fmt" + "net" + "net/http" + "os" "path" "runtime" "time" @@ -17,6 +21,8 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/xeth" ) // NewApp creates an app with sane defaults. @@ -183,3 +189,15 @@ func GetAccountManager(ctx *cli.Context) *accounts.Manager { ks := crypto.NewKeyStorePassphrase(path.Join(dataDir, "keys")) return accounts.NewManager(ks, 300*time.Second) } + +func StartRPC(eth *eth.Ethereum, ctx *cli.Context) { + addr := ctx.GlobalString(RPCListenAddrFlag.Name) + port := ctx.GlobalInt(RPCPortFlag.Name) + dataDir := ctx.GlobalString(DataDirFlag.Name) + + l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port)) + if err != nil { + Fatalf("Can't listen on %s:%d: %v", addr, port, err) + } + go http.Serve(l, rpc.JSONRPC(xeth.New(eth), dataDir)) +} diff --git a/rpc/api.go b/rpc/api.go index 9c792dd61..c3aa7186b 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -11,6 +11,7 @@ package rpc import ( "fmt" "math/big" + "path" "strings" "sync" "time" @@ -55,8 +56,8 @@ type EthereumApi struct { defaultBlockAge int64 } -func NewEthereumApi(eth *xeth.XEth) *EthereumApi { - db, _ := ethdb.NewLDBDatabase("dapps") +func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi { + db, _ := ethdb.NewLDBDatabase(path.Join(dataDir, "dapps")) api := &EthereumApi{ eth: eth, mux: eth.Backend().EventMux(), diff --git a/rpc/http.go b/rpc/http.go new file mode 100644 index 000000000..44e2ad6ab --- /dev/null +++ b/rpc/http.go @@ -0,0 +1,42 @@ +package rpc + +import ( + "net/http" + + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/xeth" +) + +var rpchttplogger = logger.NewLogger("RPC-HTTP") + +// JSONRPC returns a handler that implements the Ethereum JSON-RPC API. +func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { + var json JsonWrapper + const jsonrpcver = "2.0" + api := NewEthereumApi(pipe, dataDir) + + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + + rpchttplogger.DebugDetailln("Handling request") + + reqParsed, reqerr := json.ParseRequestBody(req) + if reqerr != nil { + jsonerr := &RpcErrorObject{-32700, "Error: Could not parse request"} + json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) + return + } + + var response interface{} + reserr := api.GetRequestReply(&reqParsed, &response) + if reserr != nil { + rpchttplogger.Warnln(reserr) + jsonerr := &RpcErrorObject{-32603, reserr.Error()} + json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Error: jsonerr}) + return + } + + rpchttplogger.DebugDetailf("Generated response: %T %s", response, response) + json.Send(w, &RpcSuccessResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Result: response}) + }) +} -- cgit v1.2.3