Merge pull request #584 from tgerring/issue577

Use ExtraDB for RPC storage. Fixes #577
This commit is contained in:
Jeffrey Wilcke 2015-03-27 11:48:03 +01:00
commit 54a14d5c9d
7 changed files with 56 additions and 61 deletions

View File

@ -9,10 +9,10 @@ import (
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/xeth" "github.com/ethereum/go-ethereum/xeth"
"github.com/robertkrimen/otto" "github.com/robertkrimen/otto"
) )
@ -69,14 +69,13 @@ func (js *jsre) startRPC(call otto.FunctionCall) otto.Value {
fmt.Println(err) fmt.Println(err)
return otto.FalseValue() return otto.FalseValue()
} }
dataDir := js.ethereum.DataDir
l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port)) l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port))
if err != nil { if err != nil {
fmt.Printf("Can't listen on %s:%d: %v", addr, port, err) fmt.Printf("Can't listen on %s:%d: %v", addr, port, err)
return otto.FalseValue() return otto.FalseValue()
} }
go http.Serve(l, rpc.JSONRPC(xeth.New(js.ethereum, nil), dataDir)) go http.Serve(l, rpc.JSONRPC(xeth.New(js.ethereum, nil)))
return otto.TrueValue() return otto.TrueValue()
} }

View File

@ -91,8 +91,7 @@ func newJSRE(ethereum *eth.Ethereum, libPath string, interactive bool) *jsre {
func (js *jsre) apiBindings() { func (js *jsre) apiBindings() {
ethApi := rpc.NewEthereumApi(js.xeth, js.ethereum.DataDir) ethApi := rpc.NewEthereumApi(js.xeth)
ethApi.Close()
//js.re.Bind("jeth", rpc.NewJeth(ethApi, js.re.ToVal)) //js.re.Bind("jeth", rpc.NewJeth(ethApi, js.re.ToVal))
jeth := rpc.NewJeth(ethApi, js.re.ToVal, js.re) jeth := rpc.NewJeth(ethApi, js.re.ToVal, js.re)

View File

@ -251,11 +251,10 @@ func GetAccountManager(ctx *cli.Context) *accounts.Manager {
func StartRPC(eth *eth.Ethereum, ctx *cli.Context) { func StartRPC(eth *eth.Ethereum, ctx *cli.Context) {
addr := ctx.GlobalString(RPCListenAddrFlag.Name) addr := ctx.GlobalString(RPCListenAddrFlag.Name)
port := ctx.GlobalInt(RPCPortFlag.Name) port := ctx.GlobalInt(RPCPortFlag.Name)
dataDir := ctx.GlobalString(DataDirFlag.Name)
fmt.Println("Starting RPC on port: ", port) fmt.Println("Starting RPC on port: ", port)
l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port)) l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port))
if err != nil { if err != nil {
Fatalf("Can't listen on %s:%d: %v", addr, port, err) Fatalf("Can't listen on %s:%d: %v", addr, port, err)
} }
go http.Serve(l, rpc.JSONRPC(xeth.New(eth, nil), dataDir)) go http.Serve(l, rpc.JSONRPC(xeth.New(eth, nil)))
} }

View File

@ -3,13 +3,11 @@ package rpc
import ( import (
"encoding/json" "encoding/json"
"math/big" "math/big"
"path"
"sync" "sync"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/xeth" "github.com/ethereum/go-ethereum/xeth"
) )
@ -19,15 +17,9 @@ type EthereumApi struct {
db common.Database db common.Database
} }
func NewEthereumApi(xeth *xeth.XEth, dataDir string) *EthereumApi { func NewEthereumApi(xeth *xeth.XEth) *EthereumApi {
// What about when dataDir is empty?
db, err := ethdb.NewLDBDatabase(path.Join(dataDir, "dapps"))
if err != nil {
panic(err)
}
api := &EthereumApi{ api := &EthereumApi{
eth: xeth, eth: xeth,
db: db,
} }
return api return api
@ -44,10 +36,6 @@ func (api *EthereumApi) xethAtStateNum(num int64) *xeth.XEth {
return api.xeth().AtStateNum(num) return api.xeth().AtStateNum(num)
} }
func (api *EthereumApi) Close() {
api.db.Close()
}
func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
// Spec at https://github.com/ethereum/wiki/wiki/JSON-RPC // Spec at https://github.com/ethereum/wiki/wiki/JSON-RPC
rpclogger.Debugf("%s %s", req.Method, req.Params) rpclogger.Debugf("%s %s", req.Method, req.Params)
@ -370,7 +358,8 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
return err return err
} }
api.db.Put([]byte(args.Database+args.Key), args.Value) api.xeth().DbPut([]byte(args.Database+args.Key), args.Value)
*reply = true *reply = true
case "db_getString": case "db_getString":
args := new(DbArgs) args := new(DbArgs)
@ -382,7 +371,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
return err return err
} }
res, _ := api.db.Get([]byte(args.Database + args.Key)) res, _ := api.xeth().DbGet([]byte(args.Database + args.Key))
*reply = string(res) *reply = string(res)
case "db_putHex": case "db_putHex":
args := new(DbHexArgs) args := new(DbHexArgs)
@ -394,7 +383,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
return err return err
} }
api.db.Put([]byte(args.Database+args.Key), args.Value) api.xeth().DbPut([]byte(args.Database+args.Key), args.Value)
*reply = true *reply = true
case "db_getHex": case "db_getHex":
args := new(DbHexArgs) args := new(DbHexArgs)
@ -406,7 +395,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
return err return err
} }
res, _ := api.db.Get([]byte(args.Database + args.Key)) res, _ := api.xeth().DbGet([]byte(args.Database + args.Key))
*reply = common.ToHex(res) *reply = common.ToHex(res)
case "shh_version": case "shh_version":
*reply = api.xeth().WhisperVersion() *reply = api.xeth().WhisperVersion()

View File

@ -6,7 +6,7 @@ import (
"testing" "testing"
// "time" // "time"
"github.com/ethereum/go-ethereum/xeth" // "github.com/ethereum/go-ethereum/xeth"
) )
func TestWeb3Sha3(t *testing.T) { func TestWeb3Sha3(t *testing.T) {
@ -26,49 +26,48 @@ func TestWeb3Sha3(t *testing.T) {
} }
} }
func TestDbStr(t *testing.T) { // func TestDbStr(t *testing.T) {
jsonput := `{"jsonrpc":"2.0","method":"db_putString","params":["testDB","myKey","myString"],"id":64}` // jsonput := `{"jsonrpc":"2.0","method":"db_putString","params":["testDB","myKey","myString"],"id":64}`
jsonget := `{"jsonrpc":"2.0","method":"db_getString","params":["testDB","myKey"],"id":64}` // jsonget := `{"jsonrpc":"2.0","method":"db_getString","params":["testDB","myKey"],"id":64}`
expected := "myString" // expected := "myString"
xeth := &xeth.XEth{} // xeth := &xeth.XEth{}
api := NewEthereumApi(xeth, "") // api := NewEthereumApi(xeth)
defer api.db.Close() // var response interface{}
var response interface{}
var req RpcRequest // var req RpcRequest
json.Unmarshal([]byte(jsonput), &req) // json.Unmarshal([]byte(jsonput), &req)
_ = api.GetRequestReply(&req, &response) // _ = api.GetRequestReply(&req, &response)
json.Unmarshal([]byte(jsonget), &req) // json.Unmarshal([]byte(jsonget), &req)
_ = api.GetRequestReply(&req, &response) // _ = api.GetRequestReply(&req, &response)
if response.(string) != expected { // if response.(string) != expected {
t.Errorf("Expected %s got %s", expected, response) // t.Errorf("Expected %s got %s", expected, response)
} // }
} // }
func TestDbHexStr(t *testing.T) { // func TestDbHexStr(t *testing.T) {
jsonput := `{"jsonrpc":"2.0","method":"db_putHex","params":["testDB","beefKey","0xbeef"],"id":64}` // jsonput := `{"jsonrpc":"2.0","method":"db_putHex","params":["testDB","beefKey","0xbeef"],"id":64}`
jsonget := `{"jsonrpc":"2.0","method":"db_getHex","params":["testDB","beefKey"],"id":64}` // jsonget := `{"jsonrpc":"2.0","method":"db_getHex","params":["testDB","beefKey"],"id":64}`
expected := "0xbeef" // expected := "0xbeef"
xeth := &xeth.XEth{} // xeth := &xeth.XEth{}
api := NewEthereumApi(xeth, "") // api := NewEthereumApi(xeth)
defer api.db.Close() // defer api.db.Close()
var response interface{} // var response interface{}
var req RpcRequest // var req RpcRequest
json.Unmarshal([]byte(jsonput), &req) // json.Unmarshal([]byte(jsonput), &req)
_ = api.GetRequestReply(&req, &response) // _ = api.GetRequestReply(&req, &response)
json.Unmarshal([]byte(jsonget), &req) // json.Unmarshal([]byte(jsonget), &req)
_ = api.GetRequestReply(&req, &response) // _ = api.GetRequestReply(&req, &response)
if response.(string) != expected { // if response.(string) != expected {
t.Errorf("Expected %s got %s", expected, response) // t.Errorf("Expected %s got %s", expected, response)
} // }
} // }
// func TestFilterClose(t *testing.T) { // func TestFilterClose(t *testing.T) {
// t.Skip() // t.Skip()

View File

@ -18,8 +18,8 @@ const (
) )
// JSONRPC returns a handler that implements the Ethereum JSON-RPC API. // JSONRPC returns a handler that implements the Ethereum JSON-RPC API.
func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { func JSONRPC(pipe *xeth.XEth) http.Handler {
api := NewEthereumApi(pipe, dataDir) api := NewEthereumApi(pipe)
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// TODO this needs to be configurable // TODO this needs to be configurable

View File

@ -209,6 +209,16 @@ func (self *XEth) Accounts() []string {
return accountAddresses return accountAddresses
} }
func (self *XEth) DbPut(key, val []byte) bool {
self.backend.ExtraDb().Put(key, val)
return true
}
func (self *XEth) DbGet(key []byte) ([]byte, error) {
val, err := self.backend.ExtraDb().Get(key)
return val, err
}
func (self *XEth) PeerCount() int { func (self *XEth) PeerCount() int {
return self.backend.PeerCount() return self.backend.PeerCount()
} }