aboutsummaryrefslogtreecommitdiffstats
path: root/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'rpc')
-rw-r--r--rpc/api.go (renamed from rpc/packages.go)259
-rw-r--r--rpc/api_test.go (renamed from rpc/packages_test.go)1
-rw-r--r--rpc/args.go91
-rw-r--r--rpc/http/server.go10
-rw-r--r--rpc/messages.go (renamed from rpc/message.go)162
-rw-r--r--rpc/util.go4
-rw-r--r--rpc/ws/server.go121
7 files changed, 298 insertions, 350 deletions
diff --git a/rpc/packages.go b/rpc/api.go
index b51bde7ce..28024c206 100644
--- a/rpc/packages.go
+++ b/rpc/api.go
@@ -20,18 +20,24 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/event/filter"
"github.com/ethereum/go-ethereum/state"
+ "github.com/ethereum/go-ethereum/ui"
"github.com/ethereum/go-ethereum/xeth"
)
-const (
- defaultGasPrice = "10000000000000"
- defaultGas = "10000"
+var (
+ defaultGasPrice = big.NewInt(10000000000000)
+ defaultGas = big.NewInt(10000)
+ filterTickerTime = 15 * time.Second
)
type EthereumApi struct {
- xeth *xeth.XEth
+ eth *xeth.XEth
+ xethMu sync.RWMutex
+ mux *event.TypeMux
+
quit chan struct{}
filterManager *filter.FilterManager
@@ -45,17 +51,21 @@ type EthereumApi struct {
register map[string][]*NewTxArgs
db ethutil.Database
+
+ defaultBlockAge int64
}
func NewEthereumApi(eth *xeth.XEth) *EthereumApi {
db, _ := ethdb.NewLDBDatabase("dapps")
api := &EthereumApi{
- xeth: eth,
- quit: make(chan struct{}),
- filterManager: filter.NewFilterManager(eth.Backend().EventMux()),
- logs: make(map[int]*logFilter),
- messages: make(map[int]*whisperFilter),
- db: db,
+ eth: eth,
+ mux: eth.Backend().EventMux(),
+ quit: make(chan struct{}),
+ filterManager: filter.NewFilterManager(eth.Backend().EventMux()),
+ logs: make(map[int]*logFilter),
+ messages: make(map[int]*whisperFilter),
+ db: db,
+ defaultBlockAge: -1,
}
go api.filterManager.Start()
go api.start()
@@ -63,6 +73,64 @@ func NewEthereumApi(eth *xeth.XEth) *EthereumApi {
return api
}
+func (self *EthereumApi) setStateByBlockNumber(num int64) {
+ chain := self.xeth().Backend().ChainManager()
+ var block *types.Block
+
+ if self.defaultBlockAge < 0 {
+ num = chain.CurrentBlock().Number().Int64() + num + 1
+ }
+ block = chain.GetBlockByNumber(uint64(num))
+
+ if block != nil {
+ self.useState(state.New(block.Root(), self.xeth().Backend().Db()))
+ } else {
+ self.useState(chain.State())
+ }
+}
+
+func (self *EthereumApi) start() {
+ timer := time.NewTicker(filterTickerTime)
+ events := self.mux.Subscribe(core.ChainEvent{})
+
+done:
+ for {
+ select {
+ case ev := <-events.Chan():
+ switch ev.(type) {
+ case core.ChainEvent:
+ if self.defaultBlockAge < 0 {
+ self.setStateByBlockNumber(self.defaultBlockAge)
+ }
+ }
+ case <-timer.C:
+ self.logMut.Lock()
+ self.messagesMut.Lock()
+ for id, filter := range self.logs {
+ if time.Since(filter.timeout) > 20*time.Second {
+ self.filterManager.UninstallFilter(id)
+ delete(self.logs, id)
+ }
+ }
+
+ for id, filter := range self.messages {
+ if time.Since(filter.timeout) > 20*time.Second {
+ self.xeth().Whisper().Unwatch(id)
+ delete(self.messages, id)
+ }
+ }
+ self.logMut.Unlock()
+ self.messagesMut.Unlock()
+ case <-self.quit:
+ break done
+ }
+ }
+}
+
+func (self *EthereumApi) stop() {
+ close(self.quit)
+}
+
func (self *EthereumApi) Register(args string, reply *interface{}) error {
self.regmut.Lock()
defer self.regmut.Unlock()
@@ -95,7 +163,7 @@ func (self *EthereumApi) WatchTx(args string, reply *interface{}) error {
func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error {
var id int
- filter := core.NewFilter(self.xeth.Backend())
+ filter := core.NewFilter(self.xeth().Backend())
filter.SetOptions(toFilterOptions(args))
filter.LogsCallback = func(logs state.Logs) {
self.logMut.Lock()
@@ -120,16 +188,12 @@ func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error {
func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error {
var id int
- filter := core.NewFilter(self.xeth.Backend())
+ filter := core.NewFilter(self.xeth().Backend())
callback := func(block *types.Block) {
self.logMut.Lock()
defer self.logMut.Unlock()
- if self.logs[id] == nil {
- self.logs[id] = &logFilter{timeout: time.Now()}
- }
-
self.logs[id].add(&state.StateLog{})
}
if args == "pending" {
@@ -139,6 +203,7 @@ func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error
}
id = self.filterManager.InstallFilter(filter)
+ self.logs[id] = &logFilter{timeout: time.Now()}
*reply = id
return nil
@@ -168,7 +233,7 @@ func (self *EthereumApi) Logs(id int, reply *interface{}) error {
}
func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error {
- filter := core.NewFilter(self.xeth.Backend())
+ filter := core.NewFilter(self.xeth().Backend())
filter.SetOptions(toFilterOptions(args))
*reply = toLogs(filter.Find())
@@ -177,41 +242,54 @@ func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error
}
func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error {
- err := args.requirements()
- if err != nil {
- return err
- }
-
- if args.BlockNumber > 0 {
- *reply = p.xeth.BlockByNumber(args.BlockNumber)
+ // This seems a bit precarious Maybe worth splitting to discrete functions
+ if len(args.Hash) > 0 {
+ *reply = p.xeth().BlockByHash(args.Hash)
} else {
- *reply = p.xeth.BlockByHash(args.Hash)
+ *reply = p.xeth().BlockByNumber(args.BlockNumber)
}
return nil
}
func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error {
if len(args.Gas) == 0 {
- args.Gas = defaultGas
+ args.Gas = defaultGas.String()
}
if len(args.GasPrice) == 0 {
- args.GasPrice = defaultGasPrice
+ args.GasPrice = defaultGasPrice.String()
}
// TODO if no_private_key then
- if _, exists := p.register[args.From]; exists {
- p.register[args.From] = append(p.register[args.From], args)
- } else {
- result, _ := p.xeth.Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
- *reply = result
- }
+ //if _, exists := p.register[args.From]; exists {
+ // p.register[args.From] = append(p.register[args.From], args)
+ //} else {
+ /*
+ account := accounts.Get(fromHex(args.From))
+ if account != nil {
+ if account.Unlocked() {
+ if !unlockAccount(account) {
+ return
+ }
+ }
+
+ result, _ := account.Transact(fromHex(args.To), fromHex(args.Value), fromHex(args.Gas), fromHex(args.GasPrice), fromHex(args.Data))
+ if len(result) > 0 {
+ *reply = toHex(result)
+ }
+ } else if _, exists := p.register[args.From]; exists {
+ p.register[ags.From] = append(p.register[args.From], args)
+ }
+ */
+ result, _ := p.xeth().Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
+ *reply = result
+ //}
return nil
}
func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error {
- result, err := p.xeth.Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
+ result, err := p.xeth().Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
if err != nil {
return err
}
@@ -225,7 +303,7 @@ func (p *EthereumApi) PushTx(args *PushTxArgs, reply *interface{}) error {
if err != nil {
return err
}
- result, _ := p.xeth.PushTx(args.Tx)
+ result, _ := p.xeth().PushTx(args.Tx)
*reply = result
return nil
}
@@ -236,7 +314,7 @@ func (p *EthereumApi) GetStateAt(args *GetStateArgs, reply *interface{}) error {
return err
}
- state := p.xeth.State().SafeGet(args.Address)
+ state := p.xeth().State().SafeGet(args.Address)
value := state.StorageString(args.Key)
var hx string
@@ -258,42 +336,55 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *interface{}) err
return err
}
- *reply = p.xeth.State().SafeGet(args.Address).Storage()
+ *reply = p.xeth().State().SafeGet(args.Address).Storage()
return nil
}
func (p *EthereumApi) GetPeerCount(reply *interface{}) error {
- *reply = p.xeth.PeerCount()
+ *reply = p.xeth().PeerCount()
return nil
}
func (p *EthereumApi) GetIsListening(reply *interface{}) error {
- *reply = p.xeth.IsListening()
+ *reply = p.xeth().IsListening()
return nil
}
func (p *EthereumApi) GetCoinbase(reply *interface{}) error {
- *reply = p.xeth.Coinbase()
+ *reply = p.xeth().Coinbase()
return nil
}
func (p *EthereumApi) Accounts(reply *interface{}) error {
- *reply = p.xeth.Accounts()
+ *reply = p.xeth().Accounts()
return nil
}
func (p *EthereumApi) GetIsMining(reply *interface{}) error {
- *reply = p.xeth.IsMining()
+ *reply = p.xeth().IsMining()
return nil
}
func (p *EthereumApi) SetMining(shouldmine bool, reply *interface{}) error {
- *reply = p.xeth.SetMining(shouldmine)
+ *reply = p.xeth().SetMining(shouldmine)
+ return nil
+}
+
+func (p *EthereumApi) GetDefaultBlockAge(reply *interface{}) error {
+ *reply = p.defaultBlockAge
+ return nil
+}
+
+func (p *EthereumApi) SetDefaultBlockAge(defaultBlockAge int64, reply *interface{}) error {
+ p.defaultBlockAge = defaultBlockAge
+ p.setStateByBlockNumber(p.defaultBlockAge)
+
+ *reply = true
return nil
}
func (p *EthereumApi) BlockNumber(reply *interface{}) error {
- *reply = p.xeth.Backend().ChainManager().CurrentBlock().Number()
+ *reply = p.xeth().Backend().ChainManager().CurrentBlock().Number()
return nil
}
@@ -302,7 +393,7 @@ func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) err
if err != nil {
return err
}
- *reply = p.xeth.TxCountAt(args.Address)
+ *reply = p.xeth().TxCountAt(args.Address)
return nil
}
@@ -311,7 +402,7 @@ func (p *EthereumApi) GetBalanceAt(args *GetBalanceArgs, reply *interface{}) err
if err != nil {
return err
}
- state := p.xeth.State().SafeGet(args.Address)
+ state := p.xeth().State().SafeGet(args.Address)
*reply = toHex(state.Balance().Bytes())
return nil
}
@@ -321,7 +412,7 @@ func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error {
if err != nil {
return err
}
- *reply = p.xeth.CodeAt(args.Address)
+ *reply = p.xeth().CodeAt(args.Address)
return nil
}
@@ -368,7 +459,7 @@ func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error {
}
func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error {
- *reply = p.xeth.Whisper().NewIdentity()
+ *reply = p.xeth().Whisper().NewIdentity()
return nil
}
@@ -377,12 +468,10 @@ func (p *EthereumApi) NewWhisperFilter(args *xeth.Options, reply *interface{}) e
args.Fn = func(msg xeth.WhisperMessage) {
p.messagesMut.Lock()
defer p.messagesMut.Unlock()
- if p.messages[id] == nil {
- p.messages[id] = &whisperFilter{timeout: time.Now()}
- }
p.messages[id].add(msg) // = append(p.messages[id], msg)
}
- id = p.xeth.Whisper().Watch(args)
+ id = p.xeth().Whisper().Watch(args)
+ p.messages[id] = &whisperFilter{timeout: time.Now()}
*reply = id
return nil
}
@@ -399,7 +488,7 @@ func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error {
}
func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) error {
- err := p.xeth.Whisper().Post(args.Payload, args.To, args.From, args.Topic, args.Priority, args.Ttl)
+ err := p.xeth().Whisper().Post(args.Payload, args.To, args.From, args.Topic, args.Priority, args.Ttl)
if err != nil {
return err
}
@@ -409,17 +498,17 @@ func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{})
}
func (p *EthereumApi) HasWhisperIdentity(args string, reply *interface{}) error {
- *reply = p.xeth.Whisper().HasIdentity(args)
+ *reply = p.xeth().Whisper().HasIdentity(args)
return nil
}
func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error {
- *reply = p.xeth.Whisper().Messages(id)
+ *reply = p.xeth().Whisper().Messages(id)
return nil
}
func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
- // Spec at https://github.com/ethereum/wiki/wiki/Generic-ON-RPC
+ // Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC
rpclogger.DebugDetailf("%T %s", req.Params, req.Params)
switch req.Method {
case "eth_coinbase":
@@ -434,6 +523,14 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return err
}
return p.SetMining(args, reply)
+ case "eth_defaultBlock":
+ return p.GetDefaultBlockAge(reply)
+ case "eth_setDefaultBlock":
+ args, err := req.ToIntArgs()
+ if err != nil {
+ return err
+ }
+ return p.SetDefaultBlockAge(int64(args), reply)
case "eth_peerCount":
return p.GetPeerCount(reply)
case "eth_number":
@@ -525,7 +622,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
}
return p.AllLogs(args, reply)
case "eth_gasPrice":
- *reply = defaultGasPrice
+ *reply = toHex(defaultGasPrice.Bytes())
return nil
case "eth_register":
args, err := req.ToRegisterArgs()
@@ -604,42 +701,34 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
}
return p.WhisperMessages(args, reply)
default:
- return NewErrorResponse(fmt.Sprintf("%v %s", ErrorNotImplemented, req.Method))
+ return NewErrorWithMessage(errNotImplemented, req.Method)
}
rpclogger.DebugDetailf("Reply: %T %s", reply, reply)
return nil
}
-var filterTickerTime = 15 * time.Second
+func (self *EthereumApi) xeth() *xeth.XEth {
+ self.xethMu.RLock()
+ defer self.xethMu.RUnlock()
-func (self *EthereumApi) start() {
- timer := time.NewTicker(filterTickerTime)
-done:
- for {
- select {
- case <-timer.C:
- self.logMut.Lock()
- self.messagesMut.Lock()
- for id, filter := range self.logs {
- if time.Since(filter.timeout) > 20*time.Second {
- delete(self.logs, id)
- }
- }
+ return self.eth
+}
- for id, filter := range self.messages {
- if time.Since(filter.timeout) > 20*time.Second {
- delete(self.messages, id)
- }
- }
- self.logMut.Unlock()
- self.messagesMut.Unlock()
- case <-self.quit:
- break done
- }
- }
+func (self *EthereumApi) useState(statedb *state.StateDB) {
+ self.xethMu.Lock()
+ defer self.xethMu.Unlock()
+
+ self.eth = self.eth.UseState(statedb)
}
-func (self *EthereumApi) stop() {
- close(self.quit)
+func t(f ui.Frontend) {
+ // Call the password dialog
+ ret, err := f.Call("PasswordDialog")
+ if err != nil {
+ fmt.Println(err)
+ }
+ // Get the first argument
+ t, _ := ret.Get(0)
+ fmt.Println("return:", t)
}
diff --git a/rpc/packages_test.go b/rpc/api_test.go
index 037fd78b3..a9fc16cd3 100644
--- a/rpc/packages_test.go
+++ b/rpc/api_test.go
@@ -7,6 +7,7 @@ import (
)
func TestFilterClose(t *testing.T) {
+ t.Skip()
api := &EthereumApi{
logs: make(map[int]*logFilter),
messages: make(map[int]*whisperFilter),
diff --git a/rpc/args.go b/rpc/args.go
index f730819fd..ea8489585 100644
--- a/rpc/args.go
+++ b/rpc/args.go
@@ -19,14 +19,7 @@ func (obj *GetBlockArgs) UnmarshalJSON(b []byte) (err error) {
obj.Hash = argstr
return
}
- return NewErrorResponse(ErrorDecodeArgs)
-}
-
-func (obj *GetBlockArgs) requirements() error {
- if obj.BlockNumber == 0 && obj.Hash == "" {
- return NewErrorResponse("GetBlock requires either a block 'number' or a block 'hash' as argument")
- }
- return nil
+ return errDecodeArgs
}
type NewTxArgs struct {
@@ -64,7 +57,7 @@ func (obj *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
return
}
- return NewErrorResponse(ErrorDecodeArgs)
+ return errDecodeArgs
}
type PushTxArgs struct {
@@ -77,12 +70,12 @@ func (obj *PushTxArgs) UnmarshalJSON(b []byte) (err error) {
obj.Tx = arg0
return
}
- return NewErrorResponse(ErrorDecodeArgs)
+ return errDecodeArgs
}
func (a *PushTxArgs) requirementsPushTx() error {
if a.Tx == "" {
- return NewErrorResponse("PushTx requires a 'tx' as argument")
+ return NewErrorWithMessage(errArguments, "PushTx requires a 'tx' as argument")
}
return nil
}
@@ -93,14 +86,14 @@ type GetStorageArgs struct {
func (obj *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
if err = json.Unmarshal(b, &obj.Address); err != nil {
- return NewErrorResponse(ErrorDecodeArgs)
+ return errDecodeArgs
}
return
}
func (a *GetStorageArgs) requirements() error {
if len(a.Address) == 0 {
- return NewErrorResponse("GetStorageAt requires an 'address' value as argument")
+ return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'address' value as argument")
}
return nil
}
@@ -116,64 +109,39 @@ func (obj *GetStateArgs) UnmarshalJSON(b []byte) (err error) {
obj.Address = arg0
return
}
- return NewErrorResponse(ErrorDecodeArgs)
+ return errDecodeArgs
}
func (a *GetStateArgs) requirements() error {
if a.Address == "" {
- return NewErrorResponse("GetStorageAt requires an 'address' value as argument")
+ return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'address' value as argument")
}
if a.Key == "" {
- return NewErrorResponse("GetStorageAt requires an 'key' value as argument")
+ return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'key' value as argument")
}
return nil
}
-type GetStorageAtRes struct {
- Key string `json:"key"`
- Value string `json:"value"`
-}
-
type GetTxCountArgs struct {
Address string `json:"address"`
}
-// type GetTxCountRes struct {
-// Nonce int `json:"nonce"`
-// }
-
func (obj *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
arg0 := ""
if err = json.Unmarshal(b, &arg0); err == nil {
obj.Address = arg0
return
}
- return NewErrorResponse("Could not determine JSON parameters")
+ return errDecodeArgs
}
func (a *GetTxCountArgs) requirements() error {
if a.Address == "" {
- return NewErrorResponse("GetTxCountAt requires an 'address' value as argument")
+ return NewErrorWithMessage(errArguments, "GetTxCountAt requires an 'address' value as argument")
}
return nil
}
-// type GetPeerCountRes struct {
-// PeerCount int `json:"peerCount"`
-// }
-
-// type GetListeningRes struct {
-// IsListening bool `json:"isListening"`
-// }
-
-// type GetCoinbaseRes struct {
-// Coinbase string `json:"coinbase"`
-// }
-
-// type GetMiningRes struct {
-// IsMining bool `json:"isMining"`
-// }
-
type GetBalanceArgs struct {
Address string
}
@@ -184,21 +152,16 @@ func (obj *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
obj.Address = arg0
return
}
- return NewErrorResponse("Could not determine JSON parameters")
+ return errDecodeArgs
}
func (a *GetBalanceArgs) requirements() error {
if a.Address == "" {
- return NewErrorResponse("GetBalanceAt requires an 'address' value as argument")
+ return NewErrorWithMessage(errArguments, "GetBalanceAt requires an 'address' value as argument")
}
return nil
}
-type BalanceRes struct {
- Balance string `json:"balance"`
- Address string `json:"address"`
-}
-
type GetCodeAtArgs struct {
Address string
}
@@ -209,12 +172,12 @@ func (obj *GetCodeAtArgs) UnmarshalJSON(b []byte) (err error) {
obj.Address = arg0
return
}
- return NewErrorResponse(ErrorDecodeArgs)
+ return errDecodeArgs
}
func (a *GetCodeAtArgs) requirements() error {
if a.Address == "" {
- return NewErrorResponse("GetCodeAt requires an 'address' value as argument")
+ return NewErrorWithMessage(errArguments, "GetCodeAt requires an 'address' value as argument")
}
return nil
}
@@ -225,7 +188,7 @@ type Sha3Args struct {
func (obj *Sha3Args) UnmarshalJSON(b []byte) (err error) {
if err = json.Unmarshal(b, &obj.Data); err != nil {
- return NewErrorResponse(ErrorDecodeArgs)
+ return errDecodeArgs
}
return
}
@@ -234,7 +197,7 @@ type FilterOptions struct {
Earliest int64
Latest int64
Address interface{}
- Topic []string
+ Topic []interface{}
Skip int
Max int
}
@@ -257,10 +220,20 @@ func toFilterOptions(options *FilterOptions) core.FilterOptions {
opts.Earliest = options.Earliest
opts.Latest = options.Latest
- opts.Topics = make([][]byte, len(options.Topic))
- for i, topic := range options.Topic {
- opts.Topics[i] = fromHex(topic)
+
+ topics := make([][][]byte, len(options.Topic))
+ for i, topicDat := range options.Topic {
+ if slice, ok := topicDat.([]interface{}); ok {
+ topics[i] = make([][]byte, len(slice))
+ for j, topic := range slice {
+ topics[i][j] = fromHex(topic.(string))
+ }
+ } else if str, ok := topicDat.(string); ok {
+ topics[i] = make([][]byte, 1)
+ topics[i][0] = fromHex(str)
+ }
}
+ opts.Topics = topics
return opts
}
@@ -277,10 +250,10 @@ type DbArgs struct {
func (a *DbArgs) requirements() error {
if len(a.Database) == 0 {
- return NewErrorResponse("DbPutArgs requires an 'Database' value as argument")
+ return NewErrorWithMessage(errArguments, "DbPutArgs requires an 'Database' value as argument")
}
if len(a.Key) == 0 {
- return NewErrorResponse("DbPutArgs requires an 'Key' value as argument")
+ return NewErrorWithMessage(errArguments, "DbPutArgs requires an 'Key' value as argument")
}
return nil
}
diff --git a/rpc/http/server.go b/rpc/http/server.go
index dd6ba68e3..452b7c9af 100644
--- a/rpc/http/server.go
+++ b/rpc/http/server.go
@@ -29,8 +29,8 @@ import (
var rpchttplogger = logger.NewLogger("RPC-HTTP")
var JSON rpc.JsonWrapper
-func NewRpcHttpServer(pipe *xeth.XEth, port int) (*RpcHttpServer, error) {
- sport := fmt.Sprintf("127.0.0.1:%d", port)
+func NewRpcHttpServer(pipe *xeth.XEth, address string, port int) (*RpcHttpServer, error) {
+ sport := fmt.Sprintf("%s:%d", address, port)
l, err := net.Listen("tcp", sport)
if err != nil {
return nil, err
@@ -41,6 +41,7 @@ func NewRpcHttpServer(pipe *xeth.XEth, port int) (*RpcHttpServer, error) {
quit: make(chan bool),
pipe: pipe,
port: port,
+ addr: address,
}, nil
}
@@ -49,6 +50,7 @@ type RpcHttpServer struct {
listener net.Listener
pipe *xeth.XEth
port int
+ addr string
}
func (s *RpcHttpServer) exitHandler() {
@@ -69,7 +71,7 @@ func (s *RpcHttpServer) Stop() {
}
func (s *RpcHttpServer) Start() {
- rpchttplogger.Infof("Starting RPC-HTTP server on port %d", s.port)
+ rpchttplogger.Infof("Starting RPC-HTTP server on %s:%d", s.addr, s.port)
go s.exitHandler()
api := rpc.NewEthereumApi(s.pipe)
@@ -92,7 +94,7 @@ func (s *RpcHttpServer) apiHandler(api *rpc.EthereumApi) http.Handler {
reqParsed, reqerr := JSON.ParseRequestBody(req)
if reqerr != nil {
- jsonerr := &rpc.RpcErrorObject{-32700, rpc.ErrorParseRequest}
+ jsonerr := &rpc.RpcErrorObject{-32700, "Error: Could not parse request"}
JSON.Send(w, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr})
return
}
diff --git a/rpc/message.go b/rpc/messages.go
index 825ede05b..b37d8229d 100644
--- a/rpc/message.go
+++ b/rpc/messages.go
@@ -25,12 +25,11 @@ import (
"github.com/ethereum/go-ethereum/xeth"
)
-const (
- ErrorArguments = "Error: Insufficient arguments"
- ErrorNotImplemented = "Error: Method not implemented"
- ErrorUnknown = "Error: Unknown error"
- ErrorParseRequest = "Error: Could not parse request"
- ErrorDecodeArgs = "Error: Could not decode arguments"
+var (
+ errArguments = errors.New("Error: Insufficient arguments")
+ errNotImplemented = errors.New("Error: Method not implemented")
+ errUnknown = errors.New("Error: Unknown error")
+ errDecodeArgs = errors.New("Error: Could not decode arguments")
)
type RpcRequest struct {
@@ -58,76 +57,72 @@ type RpcErrorObject struct {
// Data interface{} `json:"data"`
}
-func NewErrorResponse(msg string) error {
- return errors.New(msg)
-}
-
-func NewErrorResponseWithError(msg string, err error) error {
- return fmt.Errorf("%s: %v", msg, err)
+func NewErrorWithMessage(err error, msg string) error {
+ return fmt.Errorf("%s: %s", err.Error(), msg)
}
func (req *RpcRequest) ToSha3Args() (*Sha3Args, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(Sha3Args)
r := bytes.NewReader(req.Params[0])
if err := json.NewDecoder(r).Decode(args); err != nil {
- return nil, NewErrorResponse(ErrorDecodeArgs)
+ return nil, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToGetBlockArgs() (*GetBlockArgs, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(GetBlockArgs)
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(args)
if err != nil {
- return nil, NewErrorResponse(ErrorDecodeArgs)
+ return nil, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToNewTxArgs() (*NewTxArgs, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(NewTxArgs)
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(args)
if err != nil {
- return nil, NewErrorResponseWithError(ErrorDecodeArgs, err)
+ return nil, NewErrorWithMessage(errDecodeArgs, err.Error())
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToPushTxArgs() (*PushTxArgs, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(PushTxArgs)
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(args)
if err != nil {
- return nil, NewErrorResponse(ErrorDecodeArgs)
+ return nil, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToGetStateArgs() (*GetStateArgs, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(GetStateArgs)
@@ -135,234 +130,241 @@ func (req *RpcRequest) ToGetStateArgs() (*GetStateArgs, error) {
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(args)
if err != nil {
- return nil, NewErrorResponse(ErrorDecodeArgs)
+ return nil, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToStorageAtArgs() (*GetStorageArgs, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(GetStorageArgs)
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(args)
if err != nil {
- return nil, NewErrorResponse(ErrorDecodeArgs)
+ return nil, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToGetTxCountArgs() (*GetTxCountArgs, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(GetTxCountArgs)
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(args)
if err != nil {
- return nil, NewErrorResponse(ErrorDecodeArgs)
+ return nil, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToGetBalanceArgs() (*GetBalanceArgs, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(GetBalanceArgs)
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(args)
if err != nil {
- return nil, NewErrorResponse(ErrorDecodeArgs)
+ return nil, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToGetCodeAtArgs() (*GetCodeAtArgs, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(GetCodeAtArgs)
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(args)
if err != nil {
- return nil, NewErrorResponse(ErrorDecodeArgs)
+ return nil, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToBoolArgs() (bool, error) {
if len(req.Params) < 1 {
- return false, NewErrorResponse(ErrorArguments)
+ return false, errArguments
}
var args bool
err := json.Unmarshal(req.Params[0], &args)
if err != nil {
- return false, NewErrorResponse(ErrorDecodeArgs)
+ return false, errDecodeArgs
+ }
+
+ return args, nil
+}
+
+func (req *RpcRequest) ToIntArgs() (int, error) {
+ if len(req.Params) < 1 {
+ return 0, errArguments
+ }
+
+ var args int
+ if err := json.Unmarshal(req.Params[0], &args); err != nil {
+ return 0, errArguments
}
- rpclogger.DebugDetailf("%T %v", args, args)
return args, nil
}
func (req *RpcRequest) ToCompileArgs() (string, error) {
if len(req.Params) < 1 {
- return "", NewErrorResponse(ErrorArguments)
+ return "", errArguments
}
var args string
err := json.Unmarshal(req.Params[0], &args)
if err != nil {
- return "", NewErrorResponse(ErrorDecodeArgs)
+ return "", errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
return args, nil
}
func (req *RpcRequest) ToFilterArgs() (*FilterOptions, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
args := new(FilterOptions)
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(args)
if err != nil {
- return nil, NewErrorResponse(ErrorDecodeArgs)
+ return nil, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
return args, nil
}
func (req *RpcRequest) ToFilterStringArgs() (string, error) {
if len(req.Params) < 1 {
- return "", NewErrorResponse(ErrorArguments)
+ return "", errArguments
}
var args string
err := json.Unmarshal(req.Params[0], &args)
if err != nil {
- return "", NewErrorResponse(ErrorDecodeArgs)
+ return "", errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
return args, nil
}
func (req *RpcRequest) ToUninstallFilterArgs() (int, error) {
if len(req.Params) < 1 {
- return 0, NewErrorResponse(ErrorArguments)
+ return 0, errArguments
}
var args int
err := json.Unmarshal(req.Params[0], &args)
if err != nil {
- return 0, NewErrorResponse(ErrorDecodeArgs)
+ return 0, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", args, args)
return args, nil
}
func (req *RpcRequest) ToFilterChangedArgs() (int, error) {
if len(req.Params) < 1 {
- return 0, NewErrorResponse(ErrorArguments)
+ return 0, errArguments
}
var id int
r := bytes.NewReader(req.Params[0])
err := json.NewDecoder(r).Decode(&id)
if err != nil {
- return 0, NewErrorResponse(ErrorDecodeArgs)
+ return 0, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", id, id)
return id, nil
}
func (req *RpcRequest) ToDbPutArgs() (*DbArgs, error) {
if len(req.Params) < 3 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
var args DbArgs
err := json.Unmarshal(req.Params[0], &args.Database)
if err != nil {
- return nil, NewErrorResponseWithError(ErrorDecodeArgs, err)
+ return nil, NewErrorWithMessage(errDecodeArgs, err.Error())
}
err = json.Unmarshal(req.Params[1], &args.Key)
if err != nil {
- return nil, NewErrorResponseWithError(ErrorDecodeArgs, err)
+ return nil, NewErrorWithMessage(errDecodeArgs, err.Error())
}
err = json.Unmarshal(req.Params[2], &args.Value)
if err != nil {
- return nil, NewErrorResponseWithError(ErrorDecodeArgs, err)
+ return nil, NewErrorWithMessage(errDecodeArgs, err.Error())
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return &args, nil
}
func (req *RpcRequest) ToDbGetArgs() (*DbArgs, error) {
if len(req.Params) < 2 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
var args DbArgs
err := json.Unmarshal(req.Params[0], &args.Database)
if err != nil {
- return nil, NewErrorResponseWithError(ErrorDecodeArgs, err)
+ return nil, NewErrorWithMessage(errDecodeArgs, err.Error())
}
err = json.Unmarshal(req.Params[1], &args.Key)
if err != nil {
- return nil, NewErrorResponseWithError(ErrorDecodeArgs, err)
+ return nil, NewErrorWithMessage(errDecodeArgs, err.Error())
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return &args, nil
}
func (req *RpcRequest) ToWhisperFilterArgs() (*xeth.Options, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
var args xeth.Options
err := json.Unmarshal(req.Params[0], &args)
if err != nil {
- return nil, NewErrorResponseWithError(ErrorDecodeArgs, err)
+ return nil, NewErrorWithMessage(errDecodeArgs, err.Error())
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return &args, nil
}
func (req *RpcRequest) ToIdArgs() (int, error) {
if len(req.Params) < 1 {
- return 0, NewErrorResponse(ErrorArguments)
+ return 0, errArguments
}
var id int
err := json.Unmarshal(req.Params[0], &id)
if err != nil {
- return 0, NewErrorResponse(ErrorDecodeArgs)
+ return 0, errDecodeArgs
}
- rpclogger.DebugDetailf("%T %v", id, id)
+
return id, nil
}
func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) {
if len(req.Params) < 1 {
- return nil, NewErrorResponse(ErrorArguments)
+ return nil, errArguments
}
var args WhisperMessageArgs
@@ -370,13 +372,13 @@ func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) {
if err != nil {
return nil, err
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return &args, nil
}
func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) {
if len(req.Params) < 1 {
- return "", NewErrorResponse(ErrorArguments)
+ return "", errArguments
}
var args string
@@ -384,13 +386,13 @@ func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) {
if err != nil {
return "", err
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToRegisterArgs() (string, error) {
if len(req.Params) < 1 {
- return "", NewErrorResponse(ErrorArguments)
+ return "", errArguments
}
var args string
@@ -398,13 +400,13 @@ func (req *RpcRequest) ToRegisterArgs() (string, error) {
if err != nil {
return "", err
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
func (req *RpcRequest) ToWatchTxArgs() (string, error) {
if len(req.Params) < 1 {
- return "", NewErrorResponse(ErrorArguments)
+ return "", errArguments
}
var args string
@@ -412,6 +414,6 @@ func (req *RpcRequest) ToWatchTxArgs() (string, error) {
if err != nil {
return "", err
}
- rpclogger.DebugDetailf("%T %v", args, args)
+
return args, nil
}
diff --git a/rpc/util.go b/rpc/util.go
index 1939b3474..3e8ca3fef 100644
--- a/rpc/util.go
+++ b/rpc/util.go
@@ -82,7 +82,7 @@ type RpcServer interface {
type Log struct {
Address string `json:"address"`
- Topic []string `json:"topics"`
+ Topic []string `json:"topic"`
Data string `json:"data"`
Number uint64 `json:"number"`
}
@@ -108,6 +108,7 @@ func toLogs(logs state.Logs) (ls []Log) {
type whisperFilter struct {
messages []xeth.WhisperMessage
timeout time.Time
+ id int
}
func (w *whisperFilter) add(msgs ...xeth.WhisperMessage) {
@@ -123,6 +124,7 @@ func (w *whisperFilter) get() []xeth.WhisperMessage {
type logFilter struct {
logs state.Logs
timeout time.Time
+ id int
}
func (l *logFilter) add(logs ...state.Log) {
diff --git a/rpc/ws/server.go b/rpc/ws/server.go
deleted file mode 100644
index b8cc2fa6b..000000000
--- a/rpc/ws/server.go
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- This file is part of go-ethereum
-
- go-ethereum is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- go-ethereum is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-*/
-package rpcws
-
-import (
- "fmt"
- "net"
- "net/http"
-
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/xeth"
- "golang.org/x/net/websocket"
-)
-
-var wslogger = logger.NewLogger("RPC-WS")
-var JSON rpc.JsonWrapper
-
-type WebSocketServer struct {
- pipe *xeth.XEth
- port int
- doneCh chan bool
- listener net.Listener
-}
-
-func NewWebSocketServer(pipe *xeth.XEth, port int) (*WebSocketServer, error) {
- sport := fmt.Sprintf(":%d", port)
- l, err := net.Listen("tcp", sport)
- if err != nil {
- return nil, err
- }
-
- return &WebSocketServer{
- pipe,
- port,
- make(chan bool),
- l,
- }, nil
-}
-
-func (self *WebSocketServer) handlerLoop() {
- for {
- select {
- case <-self.doneCh:
- wslogger.Infoln("Shutdown RPC-WS server")
- return
- }
- }
-}
-
-func (self *WebSocketServer) Stop() {
- close(self.doneCh)
-}
-
-func (self *WebSocketServer) Start() {
- wslogger.Infof("Starting RPC-WS server on port %d", self.port)
- go self.handlerLoop()
-
- api := rpc.NewEthereumApi(self.pipe)
- h := self.apiHandler(api)
- http.Handle("/ws", h)
-
- err := http.Serve(self.listener, nil)
- if err != nil {
- wslogger.Errorln("Error on RPC-WS interface:", err)
- }
-}
-
-func (s *WebSocketServer) apiHandler(api *rpc.EthereumApi) http.Handler {
- fn := func(w http.ResponseWriter, req *http.Request) {
- h := sockHandler(api)
- s := websocket.Server{Handler: h}
- s.ServeHTTP(w, req)
- }
-
- return http.HandlerFunc(fn)
-}
-
-func sockHandler(api *rpc.EthereumApi) websocket.Handler {
- var jsonrpcver string = "2.0"
- fn := func(conn *websocket.Conn) {
- for {
- wslogger.Debugln("Handling connection")
- var reqParsed rpc.RpcRequest
-
- // reqParsed, reqerr := JSON.ParseRequestBody(conn.Request())
- if err := websocket.JSON.Receive(conn, &reqParsed); err != nil {
- jsonerr := &rpc.RpcErrorObject{-32700, rpc.ErrorParseRequest}
- JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr})
- continue
- }
-
- var response interface{}
- reserr := api.GetRequestReply(&reqParsed, &response)
- if reserr != nil {
- wslogger.Warnln(reserr)
- jsonerr := &rpc.RpcErrorObject{-32603, reserr.Error()}
- JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Error: jsonerr})
- continue
- }
-
- wslogger.Debugf("Generated response: %T %s", response, response)
- JSON.Send(conn, &rpc.RpcSuccessResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Result: response})
- }
- }
- return websocket.Handler(fn)
-}