From d670c861d7b7acb9983fdad065b2b67b0d598c45 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 14:19:52 -0400 Subject: [PATCH 01/51] Move Log to LogRes --- rpc/api.go | 6 +++--- rpc/responses.go | 26 ++++++++++++++++++++++++++ rpc/util.go | 26 -------------------------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 6154a0b286..7924985471 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -208,7 +208,7 @@ func (self *EthereumApi) FilterChanged(id int, reply *interface{}) error { defer self.logMut.Unlock() if self.logs[id] != nil { - *reply = toLogs(self.logs[id].get()) + *reply = NewLogsRes(self.logs[id].get()) } return nil @@ -220,7 +220,7 @@ func (self *EthereumApi) Logs(id int, reply *interface{}) error { filter := self.filterManager.GetFilter(id) if filter != nil { - *reply = toLogs(filter.Find()) + *reply = NewLogsRes(filter.Find()) } return nil @@ -230,7 +230,7 @@ func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error filter := core.NewFilter(self.xeth().Backend()) filter.SetOptions(toFilterOptions(args)) - *reply = toLogs(filter.Find()) + *reply = NewLogsRes(filter.Find()) return nil } diff --git a/rpc/responses.go b/rpc/responses.go index eec483fb7b..a3613f3809 100644 --- a/rpc/responses.go +++ b/rpc/responses.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/state" ) type BlockRes struct { @@ -211,3 +212,28 @@ type FilterWhisperRes struct { Payload string `json:"payload"` WorkProved string `json:"workProved"` } + +type LogRes struct { + Address string `json:"address"` + Topic []string `json:"topic"` + Data string `json:"data"` + Number uint64 `json:"number"` +} + +func NewLogsRes(logs state.Logs) (ls []LogRes) { + ls = make([]LogRes, len(logs)) + + for i, log := range logs { + var l LogRes + l.Topic = make([]string, len(log.Topics())) + l.Address = common.ToHex(log.Address()) + l.Data = common.ToHex(log.Data()) + l.Number = log.Number() + for j, topic := range log.Topics() { + l.Topic[j] = common.ToHex(topic) + } + ls[i] = l + } + + return +} diff --git a/rpc/util.go b/rpc/util.go index 0798ae1d22..9a1d11bf16 100644 --- a/rpc/util.go +++ b/rpc/util.go @@ -19,7 +19,6 @@ package rpc import ( "time" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/xeth" @@ -27,31 +26,6 @@ import ( var rpclogger = logger.NewLogger("RPC") -type Log struct { - Address string `json:"address"` - Topic []string `json:"topic"` - Data string `json:"data"` - Number uint64 `json:"number"` -} - -func toLogs(logs state.Logs) (ls []Log) { - ls = make([]Log, len(logs)) - - for i, log := range logs { - var l Log - l.Topic = make([]string, len(log.Topics())) - l.Address = common.ToHex(log.Address()) - l.Data = common.ToHex(log.Data()) - l.Number = log.Number() - for j, topic := range log.Topics() { - l.Topic[j] = common.ToHex(topic) - } - ls[i] = l - } - - return -} - type whisperFilter struct { messages []xeth.WhisperMessage timeout time.Time From 1f2de6ecd546a094c4bead52c88963b74ed6b66a Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 14:21:42 -0400 Subject: [PATCH 02/51] Remove extra logger --- rpc/http.go | 4 ++-- rpc/util.go | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/rpc/http.go b/rpc/http.go index 5f2445e6c2..bf281efc31 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -10,7 +10,7 @@ import ( "github.com/ethereum/go-ethereum/xeth" ) -var rpchttplogger = logger.NewLogger("RPC-HTTP") +var rpclogger = logger.NewLogger("RPC") const ( jsonrpcver = "2.0" @@ -84,7 +84,7 @@ func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} { response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr} } - rpchttplogger.DebugDetailf("Generated response: %T %s", response, response) + rpclogger.DebugDetailf("Generated response: %T %s", response, response) return &response } diff --git a/rpc/util.go b/rpc/util.go index 9a1d11bf16..e2442b9fb3 100644 --- a/rpc/util.go +++ b/rpc/util.go @@ -19,13 +19,10 @@ package rpc import ( "time" - "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/xeth" ) -var rpclogger = logger.NewLogger("RPC") - type whisperFilter struct { messages []xeth.WhisperMessage timeout time.Time From c7b616ac14a6e349b57bad6511085d7189a19e3e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 14:28:31 -0400 Subject: [PATCH 03/51] Remove util --- rpc/api.go | 33 +++++++++++++++++++++++++++++++ rpc/util.go | 57 ----------------------------------------------------- 2 files changed, 33 insertions(+), 57 deletions(-) delete mode 100644 rpc/util.go diff --git a/rpc/api.go b/rpc/api.go index 7924985471..d00b86ac0f 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -862,3 +862,36 @@ func toFilterOptions(options *FilterOptions) core.FilterOptions { return opts } + +type whisperFilter struct { + messages []xeth.WhisperMessage + timeout time.Time + id int +} + +func (w *whisperFilter) add(msgs ...xeth.WhisperMessage) { + w.messages = append(w.messages, msgs...) +} +func (w *whisperFilter) get() []xeth.WhisperMessage { + w.timeout = time.Now() + tmp := w.messages + w.messages = nil + return tmp +} + +type logFilter struct { + logs state.Logs + timeout time.Time + id int +} + +func (l *logFilter) add(logs ...state.Log) { + l.logs = append(l.logs, logs...) +} + +func (l *logFilter) get() state.Logs { + l.timeout = time.Now() + tmp := l.logs + l.logs = nil + return tmp +} diff --git a/rpc/util.go b/rpc/util.go deleted file mode 100644 index e2442b9fb3..0000000000 --- a/rpc/util.go +++ /dev/null @@ -1,57 +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 . -*/ -package rpc - -import ( - "time" - - "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/xeth" -) - -type whisperFilter struct { - messages []xeth.WhisperMessage - timeout time.Time - id int -} - -func (w *whisperFilter) add(msgs ...xeth.WhisperMessage) { - w.messages = append(w.messages, msgs...) -} -func (w *whisperFilter) get() []xeth.WhisperMessage { - w.timeout = time.Now() - tmp := w.messages - w.messages = nil - return tmp -} - -type logFilter struct { - logs state.Logs - timeout time.Time - id int -} - -func (l *logFilter) add(logs ...state.Log) { - l.logs = append(l.logs, logs...) -} - -func (l *logFilter) get() state.Logs { - l.timeout = time.Now() - tmp := l.logs - l.logs = nil - return tmp -} From abc3d8d50a8691d9b4c2bd047807908d157e223c Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 18:06:26 -0400 Subject: [PATCH 04/51] Make send internal --- rpc/http.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rpc/http.go b/rpc/http.go index bf281efc31..3dfb677815 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -28,7 +28,7 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { // Limit request size to resist DoS if req.ContentLength > maxSizeReqLength { jsonerr := &RpcErrorObject{-32700, "Request too large"} - Send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) + send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) return } @@ -37,14 +37,14 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { body, err := ioutil.ReadAll(req.Body) if err != nil { jsonerr := &RpcErrorObject{-32700, "Could not read request body"} - Send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) + send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) } // Try to parse the request as a single var reqSingle RpcRequest if err := json.Unmarshal(body, &reqSingle); err == nil { response := RpcResponse(api, &reqSingle) - Send(w, &response) + send(w, &response) return } @@ -57,13 +57,13 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { response := RpcResponse(api, &request) resBatch[i] = response } - Send(w, resBatch) + send(w, resBatch) return } // Not a batch or single request, error jsonerr := &RpcErrorObject{-32600, "Could not decode request"} - Send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) + send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) }) } @@ -88,7 +88,7 @@ func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} { return &response } -func Send(writer io.Writer, v interface{}) (n int, err error) { +func send(writer io.Writer, v interface{}) (n int, err error) { var payload []byte payload, err = json.MarshalIndent(v, "", "\t") if err != nil { From 6cc02aadbff9c37cc623fadb21029527a11a06f4 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 19:58:59 -0400 Subject: [PATCH 05/51] Inline getStateWithNum --- rpc/api.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index d00b86ac0f..7fc8f32e24 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -81,10 +81,6 @@ func (self *EthereumApi) xethWithStateNum(num int64) *xeth.XEth { return self.xeth().WithState(st) } -func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { - return self.xethWithStateNum(num).State() -} - func (self *EthereumApi) start() { timer := time.NewTicker(filterTickerTime) done: @@ -290,8 +286,7 @@ func (p *EthereumApi) GetBalance(args *GetBalanceArgs, reply *interface{}) error if err := args.requirements(); err != nil { return err } - state := p.getStateWithNum(args.BlockNumber).SafeGet(args.Address) - *reply = common.ToHex(state.Balance().Bytes()) + *reply = common.ToHex(p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance().Bytes()) return nil } @@ -299,7 +294,7 @@ func (p *EthereumApi) GetStorage(args *GetStorageArgs, reply *interface{}) error if err := args.requirements(); err != nil { return err } - *reply = p.getStateWithNum(args.BlockNumber).SafeGet(args.Address).Storage() + *reply = p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() return nil } @@ -307,9 +302,10 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e if err := args.requirements(); err != nil { return err } - state := p.getStateWithNum(args.BlockNumber).SafeGet(args.Address) + state := p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address) value := state.StorageString(args.Key) + var hx string if strings.Index(args.Key, "0x") == 0 { hx = string([]byte(args.Key)[2:]) From b7745c683529bc60139d4af7fec2bf849928bfe7 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:00:18 -0400 Subject: [PATCH 06/51] inline HasWhisperIdentity --- rpc/api.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 7fc8f32e24..54efd60051 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -416,11 +416,6 @@ func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) return nil } -func (p *EthereumApi) HasWhisperIdentity(args string, reply *interface{}) error { - *reply = p.xeth().Whisper().HasIdentity(args) - return nil -} - func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error { *reply = p.xeth().Whisper().Messages(id) return nil @@ -763,7 +758,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.HasWhisperIdentity(args.Identity, reply) + *reply = p.xeth().Whisper().HasIdentity(args.Identity) case "shh_newGroup", "shh_addToGroup": return NewNotImplementedError(req.Method) case "shh_newFilter": From 7562bc1dbc23b0b8a384de29729ea24daa5c45a0 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:00:41 -0400 Subject: [PATCH 07/51] inline GetBalance --- rpc/api.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 54efd60051..5654ee3d3a 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -282,14 +282,6 @@ func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error { return nil } -func (p *EthereumApi) GetBalance(args *GetBalanceArgs, reply *interface{}) error { - if err := args.requirements(); err != nil { - return err - } - *reply = common.ToHex(p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance().Bytes()) - return nil -} - func (p *EthereumApi) GetStorage(args *GetStorageArgs, reply *interface{}) error { if err := args.requirements(); err != nil { return err @@ -506,7 +498,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.GetBalance(args, reply) + + if err := args.requirements(); err != nil { + return err + } + + *reply = common.ToHex(p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance().Bytes()) case "eth_getStorage", "eth_storageAt": args := new(GetStorageArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 3aea64510671c8f411f2efb0fed09e371027f9e6 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:02:31 -0400 Subject: [PATCH 08/51] inline GetStorage --- rpc/api.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 5654ee3d3a..d916186718 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -282,14 +282,6 @@ func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error { return nil } -func (p *EthereumApi) GetStorage(args *GetStorageArgs, reply *interface{}) error { - if err := args.requirements(); err != nil { - return err - } - *reply = p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() - return nil -} - func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) error { if err := args.requirements(); err != nil { return err @@ -509,7 +501,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.GetStorage(args, reply) + + if err := args.requirements(); err != nil { + return err + } + + *reply = p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() case "eth_getStorageAt": args := new(GetStorageAtArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From e530c960a4b334815b3c9563b8b0b6809c082548 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:03:27 -0400 Subject: [PATCH 09/51] inline GetTxCountAt --- rpc/api.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index d916186718..820bb23b00 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -303,15 +303,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) error { - err := args.requirements() - if err != nil { - return err - } - *reply = p.xethWithStateNum(args.BlockNumber).TxCountAt(args.Address) - return nil -} - func (p *EthereumApi) GetData(args *GetDataArgs, reply *interface{}) error { if err := args.requirements(); err != nil { return err @@ -518,7 +509,13 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.GetTxCountAt(args, reply) + + err := args.requirements() + if err != nil { + return err + } + + *reply = p.xethWithStateNum(args.BlockNumber).TxCountAt(args.Address) case "eth_getBlockTransactionCountByHash": args := new(GetBlockByHashArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 152b37ee116db8faa4d6dbc254336ba1fa7e94ab Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:04:02 -0400 Subject: [PATCH 10/51] inline GetData --- rpc/api.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 820bb23b00..f8ba822762 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -303,14 +303,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) GetData(args *GetDataArgs, reply *interface{}) error { - if err := args.requirements(); err != nil { - return err - } - *reply = p.xethWithStateNum(args.BlockNumber).CodeAt(args.Address) - return nil -} - func (p *EthereumApi) GetCompilers(reply *interface{}) error { c := []string{""} *reply = c @@ -565,7 +557,10 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.GetData(args, reply) + if err := args.requirements(); err != nil { + return err + } + *reply = p.xethWithStateNum(args.BlockNumber).CodeAt(args.Address) case "eth_sendTransaction", "eth_transact": args := new(NewTxArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From d28cd0f04086ce618f16b5019d2fd3992469755a Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:04:40 -0400 Subject: [PATCH 11/51] inline GetCompilers --- rpc/api.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index f8ba822762..432959bc22 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -303,12 +303,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) GetCompilers(reply *interface{}) error { - c := []string{""} - *reply = c - return nil -} - func (p *EthereumApi) DbPut(args *DbArgs, reply *interface{}) error { if err := args.requirements(); err != nil { return err @@ -670,7 +664,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error } *reply = uncle case "eth_getCompilers": - return p.GetCompilers(reply) + c := []string{""} + *reply = c case "eth_compileSolidity", "eth_compileLLL", "eth_compileSerpent": return NewNotImplementedError(req.Method) case "eth_newFilter": From 6fef6168705a9e70f36560b100d276092ecb5bff Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:05:48 -0400 Subject: [PATCH 12/51] inline DbPut --- rpc/api.go | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 432959bc22..62b8199f1f 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -303,16 +303,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) DbPut(args *DbArgs, reply *interface{}) error { - if err := args.requirements(); err != nil { - return err - } - - p.db.Put([]byte(args.Database+args.Key), []byte(args.Value)) - *reply = true - return nil -} - func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error { if err := args.requirements(); err != nil { return err @@ -711,7 +701,13 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.DbPut(args, reply) + + if err := args.requirements(); err != nil { + return err + } + + p.db.Put([]byte(args.Database+args.Key), []byte(args.Value)) + *reply = true case "db_getString": args := new(DbArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 57f6a3b5c06f1fcb6bfff5741a6f69f6cf55d89d Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:06:35 -0400 Subject: [PATCH 13/51] inline DbGet --- rpc/api.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 62b8199f1f..e2a18528bf 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -303,16 +303,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error { - if err := args.requirements(); err != nil { - return err - } - - res, _ := p.db.Get([]byte(args.Database + args.Key)) - *reply = string(res) - return nil -} - func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error { *reply = p.xeth().Whisper().NewIdentity() return nil @@ -713,7 +703,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.DbGet(args, reply) + if err := args.requirements(); err != nil { + return err + } + + res, _ := p.db.Get([]byte(args.Database + args.Key)) + *reply = string(res) case "db_putHex", "db_getHex": return NewNotImplementedError(req.Method) case "shh_post": From 85e03217de038fc84f5161c81468ed7f218bd876 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:09:54 -0400 Subject: [PATCH 14/51] inline NewWhisperIdentity --- rpc/api.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index e2a18528bf..0d67afca06 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -303,11 +303,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error { - *reply = p.xeth().Whisper().NewIdentity() - return nil -} - // func (p *EthereumApi) RemoveWhisperIdentity(args *WhisperIdentityArgs, reply *interface{}) error { // *reply = p.xeth().Whisper().RemoveIdentity(args.Identity) // return nil @@ -703,6 +698,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } + if err := args.requirements(); err != nil { return err } @@ -718,7 +714,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error } return p.WhisperPost(args, reply) case "shh_newIdentity": - return p.NewWhisperIdentity(reply) + *reply = p.xeth().Whisper().NewIdentity() // case "shh_removeIdentity": // args := new(WhisperIdentityArgs) // if err := json.Unmarshal(req.Params, &args); err != nil { From 0eb9572d642ee7fe5d730b6396f5c348c482e7d6 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:10:05 -0400 Subject: [PATCH 15/51] inline RemoveWhisperIdentity --- rpc/api.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 0d67afca06..7ecde4c24e 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -303,11 +303,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -// func (p *EthereumApi) RemoveWhisperIdentity(args *WhisperIdentityArgs, reply *interface{}) error { -// *reply = p.xeth().Whisper().RemoveIdentity(args.Identity) -// return nil -// } - func (p *EthereumApi) NewWhisperFilter(args *WhisperFilterArgs, reply *interface{}) error { var id int opts := new(xeth.Options) @@ -720,7 +715,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error // if err := json.Unmarshal(req.Params, &args); err != nil { // return err // } - // return p.RemoveWhisperIdentity(args, reply) + // *reply = p.xeth().Whisper().RemoveIdentity(args.Identity) case "shh_hasIdentity": args := new(WhisperIdentityArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From cc91ba0add5e21a6d2f67a16ee5f08b74b597edd Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:12:12 -0400 Subject: [PATCH 16/51] inline GetTransactionByHash --- rpc/api.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 7ecde4c24e..ff89bbecf5 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -352,14 +352,6 @@ func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error { return nil } -func (p *EthereumApi) GetTransactionByHash(hash string, reply *interface{}) error { - tx := p.xeth().EthTransactionByHash(hash) - if tx != nil { - *reply = NewTransactionRes(tx) - } - return nil -} - func (p *EthereumApi) GetBlockByHash(blockhash string, includetx bool) (*BlockRes, error) { block := p.xeth().EthBlockByHash(blockhash) br := NewBlockRes(block) @@ -566,7 +558,10 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error args := new(HashIndexArgs) if err := json.Unmarshal(req.Params, &args); err != nil { } - return p.GetTransactionByHash(args.Hash, reply) + tx := p.xeth().EthTransactionByHash(hash) + if tx != nil { + *reply = NewTransactionRes(tx) + } case "eth_getTransactionByBlockHashAndIndex": args := new(HashIndexArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From b28e6d830606346d42d46ab657d3ba2b5b1a994e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:12:52 -0400 Subject: [PATCH 17/51] inline WhisperMessages --- rpc/api.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index ff89bbecf5..2b2467400b 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -347,11 +347,6 @@ func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) return nil } -func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error { - *reply = p.xeth().Whisper().Messages(id) - return nil -} - func (p *EthereumApi) GetBlockByHash(blockhash string, includetx bool) (*BlockRes, error) { block := p.xeth().EthBlockByHash(blockhash) br := NewBlockRes(block) @@ -742,7 +737,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.WhisperMessages(args.Id, reply) + *reply = p.xeth().Whisper().Messages(id) // case "eth_register": // args, err := req.ToRegisterArgs() // if err != nil { From 22546dcb5528109de910e722cfc1afd5446eb3eb Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:14:27 -0400 Subject: [PATCH 18/51] inline UninstallWhisperFilter --- rpc/api.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 2b2467400b..cd34934cfa 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -320,12 +320,6 @@ func (p *EthereumApi) NewWhisperFilter(args *WhisperFilterArgs, reply *interface return nil } -func (p *EthereumApi) UninstallWhisperFilter(id int, reply *interface{}) error { - delete(p.messages, id) - *reply = true - return nil -} - func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { self.messagesMut.Lock() defer self.messagesMut.Unlock() @@ -725,7 +719,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.UninstallWhisperFilter(args.Id, reply) + + if _, ok := p.messages[args.Id]; ok { + delete(p.messages, args.Id) + } + + *reply = true case "shh_getFilterChanges": args := new(FilterIdArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 7e6c8a411d73f1406ec12d6a75225a2a60fdfa45 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:26:09 -0400 Subject: [PATCH 19/51] fixes --- rpc/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index cd34934cfa..fcab90f3b4 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -547,7 +547,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error args := new(HashIndexArgs) if err := json.Unmarshal(req.Params, &args); err != nil { } - tx := p.xeth().EthTransactionByHash(hash) + tx := p.xeth().EthTransactionByHash(args.Hash) if tx != nil { *reply = NewTransactionRes(tx) } @@ -736,7 +736,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - *reply = p.xeth().Whisper().Messages(id) + *reply = p.xeth().Whisper().Messages(args.Id) // case "eth_register": // args, err := req.ToRegisterArgs() // if err != nil { From 216175c265e7c5a82e47df3302f285104593dfa8 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:28:25 -0400 Subject: [PATCH 20/51] inline GetBlockUncleCountByNumber --- rpc/api.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index fcab90f3b4..acec7f457a 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -373,12 +373,6 @@ func (p *EthereumApi) GetBlockUncleCountByHash(blockhash string) (int64, error) return int64(len(br.Uncles)), nil } -func (p *EthereumApi) GetBlockUncleCountByNumber(blocknum int64) (int64, error) { - block := p.xeth().EthBlockByNumber(blocknum) - br := NewBlockRes(block) - return int64(len(br.Uncles)), nil -} - func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { // Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC rpclogger.Debugf("%s %s", req.Method, req.Params) @@ -492,11 +486,9 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockUncleCountByNumber(args.BlockNumber) - if err != nil { - return err - } - *reply = common.ToHex(big.NewInt(v).Bytes()) + block := p.xeth().EthBlockByNumber(args.BlockNumber) + br := NewBlockRes(block) + *reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes()) case "eth_getData", "eth_getCode": args := new(GetDataArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From c57eb286d66c01af0116e12a2476f546727e88ae Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:29:46 -0400 Subject: [PATCH 21/51] inline GetBlockUncleCountByHash --- rpc/api.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index acec7f457a..b17b513179 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -367,12 +367,6 @@ func (p *EthereumApi) GetBlockTransactionCountByNumber(blocknum int64) (int64, e return int64(len(br.Transactions)), nil } -func (p *EthereumApi) GetBlockUncleCountByHash(blockhash string) (int64, error) { - block := p.xeth().EthBlockByHash(blockhash) - br := NewBlockRes(block) - return int64(len(br.Uncles)), nil -} - func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { // Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC rpclogger.Debugf("%s %s", req.Method, req.Params) @@ -475,11 +469,9 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockUncleCountByHash(args.BlockHash) - if err != nil { - return err - } - *reply = common.ToHex(big.NewInt(v).Bytes()) + block := p.xeth().EthBlockByHash(args.BlockHash) + br := NewBlockRes(block) + *reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes()) case "eth_getUncleCountByBlockNumber": args := new(GetBlockByNumberArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From ff657edbb6222db826175965f9ec5b26dbf4385e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:30:42 -0400 Subject: [PATCH 22/51] inline GetBlockTransactionCountByNumber --- rpc/api.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index b17b513179..b9e2ca09da 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -361,12 +361,6 @@ func (p *EthereumApi) GetBlockTransactionCountByHash(blockhash string) (int64, e return int64(len(br.Transactions)), nil } -func (p *EthereumApi) GetBlockTransactionCountByNumber(blocknum int64) (int64, error) { - block := p.xeth().EthBlockByNumber(blocknum) - br := NewBlockRes(block) - return int64(len(br.Transactions)), nil -} - func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { // Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC rpclogger.Debugf("%s %s", req.Method, req.Params) @@ -458,11 +452,9 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockTransactionCountByNumber(args.BlockNumber) - if err != nil { - return err - } - *reply = common.ToHex(big.NewInt(v).Bytes()) + block := p.xeth().EthBlockByNumber(args.BlockNumber) + br := NewBlockRes(block) + *reply = common.ToHex(big.NewInt(int64(len(br.Transactions))).Bytes()) case "eth_getUncleCountByBlockHash": args := new(GetBlockByHashArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 0895190b64204205ed9cbc52a65b1060db4e43b4 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:31:40 -0400 Subject: [PATCH 23/51] inline GetBlockTransactionCountByHash --- rpc/api.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index b9e2ca09da..ded8b0296a 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -355,12 +355,6 @@ func (p *EthereumApi) GetBlockByNumber(blocknum int64, includetx bool) (*BlockRe return br, nil } -func (p *EthereumApi) GetBlockTransactionCountByHash(blockhash string) (int64, error) { - block := p.xeth().EthBlockByHash(blockhash) - br := NewBlockRes(block) - return int64(len(br.Transactions)), nil -} - func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { // Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC rpclogger.Debugf("%s %s", req.Method, req.Params) @@ -441,11 +435,9 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockTransactionCountByHash(args.BlockHash) - if err != nil { - return err - } - *reply = common.ToHex(big.NewInt(v).Bytes()) + block := p.xeth().EthBlockByHash(args.BlockHash) + br := NewBlockRes(block) + *reply = common.ToHex(big.NewInt(int64(len(br.Transactions))).Bytes()) case "eth_getBlockTransactionCountByNumber": args := new(GetBlockByNumberArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From cdfc03dc8e11a1738cad8009095549ea2d4b8287 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 20:40:50 -0400 Subject: [PATCH 24/51] inline WhisperPost --- rpc/api.go | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index ded8b0296a..9614404933 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -331,16 +331,6 @@ func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { return nil } -func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) error { - err := p.xeth().Whisper().Post(args.Payload, args.To, args.From, args.Topics, args.Priority, args.Ttl) - if err != nil { - return err - } - - *reply = true - return nil -} - func (p *EthereumApi) GetBlockByHash(blockhash string, includetx bool) (*BlockRes, error) { block := p.xeth().EthBlockByHash(blockhash) br := NewBlockRes(block) @@ -659,7 +649,13 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.WhisperPost(args, reply) + + err := p.xeth().Whisper().Post(args.Payload, args.To, args.From, args.Topics, args.Priority, args.Ttl) + if err != nil { + return err + } + + *reply = true case "shh_newIdentity": *reply = p.xeth().Whisper().NewIdentity() // case "shh_removeIdentity": From 6c04c19eb4506efa5f6de47561025b3702619f79 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 22:58:07 -0400 Subject: [PATCH 25/51] Reorg filter logic to XEth --- core/filter.go | 2 +- event/filter/eth_filter.go | 4 +- rpc/api.go | 191 +++++----------------------------- rpc/api_test.go | 64 ++++++------ rpc/args.go | 10 ++ xeth/xeth.go | 205 ++++++++++++++++++++++++++++++++++++- 6 files changed, 273 insertions(+), 203 deletions(-) diff --git a/core/filter.go b/core/filter.go index 487e82902e..f64ab4c07f 100644 --- a/core/filter.go +++ b/core/filter.go @@ -46,7 +46,7 @@ func NewFilter(eth Backend) *Filter { // SetOptions copies the filter options to the filter it self. The reason for this "silly" copy // is simply because named arguments in this case is extremely nice and readable. -func (self *Filter) SetOptions(options FilterOptions) { +func (self *Filter) SetOptions(options *FilterOptions) { self.earliest = options.Earliest self.latest = options.Latest self.skip = options.Skip diff --git a/event/filter/eth_filter.go b/event/filter/eth_filter.go index cb75d7e1a0..4406372dbe 100644 --- a/event/filter/eth_filter.go +++ b/event/filter/eth_filter.go @@ -48,7 +48,9 @@ func (self *FilterManager) InstallFilter(filter *core.Filter) (id int) { func (self *FilterManager) UninstallFilter(id int) { self.filterMu.Lock() defer self.filterMu.Unlock() - delete(self.filters, id) + if _, ok := self.filters[id]; ok { + delete(self.filters, id) + } } // GetFilter retrieves a filter installed using InstallFilter. diff --git a/rpc/api.go b/rpc/api.go index 4f86e703da..85f798c7c7 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -7,7 +7,6 @@ import ( "path" "strings" "sync" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -15,15 +14,13 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/event/filter" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/xeth" ) var ( - defaultGasPrice = big.NewInt(150000000000) - defaultGas = big.NewInt(500000) - filterTickerTime = 5 * time.Minute + defaultGasPrice = big.NewInt(150000000000) + defaultGas = big.NewInt(500000) ) type EthereumApi struct { @@ -31,17 +28,9 @@ type EthereumApi struct { xethMu sync.RWMutex mux *event.TypeMux - quit chan struct{} - filterManager *filter.FilterManager - - logMut sync.RWMutex - logs map[int]*logFilter - - messagesMut sync.RWMutex - messages map[int]*whisperFilter - // Register keeps a list of accounts and transaction data - regmut sync.Mutex - register map[string][]*NewTxArgs + // // Register keeps a list of accounts and transaction data + // regmut sync.Mutex + // register map[string][]*NewTxArgs db common.Database } @@ -49,16 +38,10 @@ type EthereumApi struct { func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi { db, _ := ethdb.NewLDBDatabase(path.Join(dataDir, "dapps")) api := &EthereumApi{ - 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, + eth: eth, + mux: eth.Backend().EventMux(), + db: db, } - go api.filterManager.Start() - go api.start() return api } @@ -85,39 +68,6 @@ func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { return self.xethWithStateNum(num).State() } -func (self *EthereumApi) start() { - timer := time.NewTicker(2 * time.Second) -done: - for { - select { - case <-timer.C: - self.logMut.Lock() - self.messagesMut.Lock() - for id, filter := range self.logs { - if time.Since(filter.timeout) > filterTickerTime { - self.filterManager.UninstallFilter(id) - delete(self.logs, id) - } - } - - for id, filter := range self.messages { - if time.Since(filter.timeout) > filterTickerTime { - self.xeth().Whisper().Unwatch(id) - delete(self.messages, id) - } - } - self.messagesMut.Unlock() - self.logMut.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() @@ -149,91 +99,43 @@ func (self *EthereumApi) stop() { // } func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error { - var id int - filter := core.NewFilter(self.xeth().Backend()) - filter.SetOptions(toFilterOptions(args)) - filter.LogsCallback = func(logs state.Logs) { - self.logMut.Lock() - defer self.logMut.Unlock() - - self.logs[id].add(logs...) - } - id = self.filterManager.InstallFilter(filter) - self.logs[id] = &logFilter{timeout: time.Now()} - + opts := toFilterOptions(args) + id := self.xeth().RegisterFilter(opts) *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) return nil } func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error { - if _, ok := self.logs[id]; ok { - delete(self.logs, id) - } + *reply = self.xeth().UninstallFilter(id) - self.filterManager.UninstallFilter(id) - *reply = true return nil } func (self *EthereumApi) NewFilterString(args *FilterStringArgs, reply *interface{}) error { - var id int - filter := core.NewFilter(self.xeth().Backend()) - - callback := func(block *types.Block, logs state.Logs) { - self.logMut.Lock() - defer self.logMut.Unlock() - - for _, log := range logs { - self.logs[id].add(log) - } - self.logs[id].add(&state.StateLog{}) - } - - switch args.Word { - case "pending": - filter.PendingCallback = callback - case "latest": - filter.BlockCallback = callback - default: - return NewValidationError("Word", "Must be `latest` or `pending`") + if err := args.requirements(); err != nil { + return err } - id = self.filterManager.InstallFilter(filter) - self.logs[id] = &logFilter{timeout: time.Now()} + id := self.xeth().NewFilterString(args.Word) *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) - return nil } func (self *EthereumApi) FilterChanged(id int, reply *interface{}) error { - self.logMut.Lock() - defer self.logMut.Unlock() - - if self.logs[id] != nil { - *reply = NewLogsRes(self.logs[id].get()) - } - + *reply = NewLogsRes(self.xeth().FilterChanged(id)) return nil } func (self *EthereumApi) Logs(id int, reply *interface{}) error { - self.logMut.Lock() - defer self.logMut.Unlock() - - filter := self.filterManager.GetFilter(id) - if filter != nil { - *reply = NewLogsRes(filter.Find()) - } + *reply = NewLogsRes(self.xeth().Logs(id)) return nil } func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error { - filter := core.NewFilter(self.xeth().Backend()) - filter.SetOptions(toFilterOptions(args)) - - *reply = NewLogsRes(filter.Find()) + opts := toFilterOptions(args) + *reply = NewLogsRes(self.xeth().AllLogs(opts)) return nil } @@ -385,36 +287,22 @@ func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error { // } func (p *EthereumApi) NewWhisperFilter(args *WhisperFilterArgs, reply *interface{}) error { - var id int opts := new(xeth.Options) opts.From = args.From opts.To = args.To opts.Topics = args.Topics - opts.Fn = func(msg xeth.WhisperMessage) { - p.messagesMut.Lock() - defer p.messagesMut.Unlock() - p.messages[id].add(msg) // = append(p.messages[id], msg) - } - id = p.xeth().Whisper().Watch(opts) - p.messages[id] = &whisperFilter{timeout: time.Now()} + id := p.xeth().NewWhisperFilter(opts) *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) return nil } func (p *EthereumApi) UninstallWhisperFilter(id int, reply *interface{}) error { - delete(p.messages, id) - *reply = true + *reply = p.xeth().UninstallWhisperFilter(id) return nil } func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { - self.messagesMut.Lock() - defer self.messagesMut.Unlock() - - if self.messages[id] != nil { - *reply = self.messages[id].get() - } - + *reply = self.xeth().MessagesChanged(id) return nil } @@ -835,7 +723,7 @@ func (self *EthereumApi) xeth() *xeth.XEth { return self.eth } -func toFilterOptions(options *FilterOptions) core.FilterOptions { +func toFilterOptions(options *FilterOptions) *core.FilterOptions { var opts core.FilterOptions // Convert optional address slice/string to byte slice @@ -868,38 +756,5 @@ func toFilterOptions(options *FilterOptions) core.FilterOptions { } opts.Topics = topics - return opts -} - -type whisperFilter struct { - messages []xeth.WhisperMessage - timeout time.Time - id int -} - -func (w *whisperFilter) add(msgs ...xeth.WhisperMessage) { - w.messages = append(w.messages, msgs...) -} -func (w *whisperFilter) get() []xeth.WhisperMessage { - w.timeout = time.Now() - tmp := w.messages - w.messages = nil - return tmp -} - -type logFilter struct { - logs state.Logs - timeout time.Time - id int -} - -func (l *logFilter) add(logs ...state.Log) { - l.logs = append(l.logs, logs...) -} - -func (l *logFilter) get() state.Logs { - l.timeout = time.Now() - tmp := l.logs - l.logs = nil - return tmp + return &opts } diff --git a/rpc/api_test.go b/rpc/api_test.go index ec03822c5b..727ade007d 100644 --- a/rpc/api_test.go +++ b/rpc/api_test.go @@ -2,9 +2,9 @@ package rpc import ( "encoding/json" - "sync" + // "sync" "testing" - "time" + // "time" ) func TestWeb3Sha3(t *testing.T) { @@ -24,33 +24,33 @@ func TestWeb3Sha3(t *testing.T) { } } -func TestFilterClose(t *testing.T) { - t.Skip() - api := &EthereumApi{ - logs: make(map[int]*logFilter), - messages: make(map[int]*whisperFilter), - quit: make(chan struct{}), - } - - filterTickerTime = 1 - api.logs[0] = &logFilter{} - api.messages[0] = &whisperFilter{} - var wg sync.WaitGroup - wg.Add(1) - go api.start() - go func() { - select { - case <-time.After(500 * time.Millisecond): - api.stop() - wg.Done() - } - }() - wg.Wait() - if len(api.logs) != 0 { - t.Error("expected logs to be empty") - } - - if len(api.messages) != 0 { - t.Error("expected messages to be empty") - } -} +// func TestFilterClose(t *testing.T) { +// t.Skip() +// api := &EthereumApi{ +// logs: make(map[int]*logFilter), +// messages: make(map[int]*whisperFilter), +// quit: make(chan struct{}), +// } + +// filterTickerTime = 1 +// api.logs[0] = &logFilter{} +// api.messages[0] = &whisperFilter{} +// var wg sync.WaitGroup +// wg.Add(1) +// go api.start() +// go func() { +// select { +// case <-time.After(500 * time.Millisecond): +// api.stop() +// wg.Done() +// } +// }() +// wg.Wait() +// if len(api.logs) != 0 { +// t.Error("expected logs to be empty") +// } + +// if len(api.messages) != 0 { +// t.Error("expected messages to be empty") +// } +// } diff --git a/rpc/args.go b/rpc/args.go index ab1c405850..bd6be5a0f3 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -609,6 +609,16 @@ func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) { return nil } +func (args *FilterStringArgs) requirements() error { + switch args.Word { + case "latest", "pending": + break + default: + return NewValidationError("Word", "Must be `latest` or `pending`") + } + return nil +} + type FilterIdArgs struct { Id int } diff --git a/xeth/xeth.go b/xeth/xeth.go index 115bd787ae..922fce8f11 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -6,6 +6,8 @@ import ( "encoding/json" "fmt" "math/big" + "sync" + "time" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" @@ -13,13 +15,17 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/event/filter" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/whisper" ) -var pipelogger = logger.NewLogger("XETH") +var ( + pipelogger = logger.NewLogger("XETH") + filterTickerTime = 5 * time.Minute +) // to resolve the import cycle type Backend interface { @@ -71,6 +77,15 @@ type XEth struct { whisper *Whisper frontend Frontend + + quit chan struct{} + filterManager *filter.FilterManager + + logMut sync.RWMutex + logs map[int]*logFilter + + messagesMut sync.RWMutex + messages map[int]*whisperFilter } // dummyFrontend is a non-interactive frontend that allows all @@ -90,15 +105,55 @@ func New(eth Backend, frontend Frontend) *XEth { chainManager: eth.ChainManager(), accountManager: eth.AccountManager(), whisper: NewWhisper(eth.Whisper()), + quit: make(chan struct{}), + filterManager: filter.NewFilterManager(eth.EventMux()), frontend: frontend, + logs: make(map[int]*logFilter), + messages: make(map[int]*whisperFilter), } if frontend == nil { xeth.frontend = dummyFrontend{} } xeth.state = NewState(xeth, xeth.chainManager.TransState()) + go xeth.start() + go xeth.filterManager.Start() + return xeth } +func (self *XEth) start() { + timer := time.NewTicker(2 * time.Second) +done: + for { + select { + case <-timer.C: + self.logMut.Lock() + self.messagesMut.Lock() + for id, filter := range self.logs { + if time.Since(filter.timeout) > filterTickerTime { + self.filterManager.UninstallFilter(id) + delete(self.logs, id) + } + } + + for id, filter := range self.messages { + if time.Since(filter.timeout) > filterTickerTime { + self.Whisper().Unwatch(id) + delete(self.messages, id) + } + } + self.messagesMut.Unlock() + self.logMut.Unlock() + case <-self.quit: + break done + } + } +} + +func (self *XEth) stop() { + close(self.quit) +} + func (self *XEth) Backend() Backend { return self.eth } func (self *XEth) WithState(statedb *state.StateDB) *XEth { xeth := &XEth{ @@ -241,6 +296,121 @@ func (self *XEth) SecretToAddress(key string) string { return common.ToHex(pair.Address()) } +func (self *XEth) RegisterFilter(args *core.FilterOptions) int { + var id int + filter := core.NewFilter(self.Backend()) + filter.SetOptions(args) + filter.LogsCallback = func(logs state.Logs) { + self.logMut.Lock() + defer self.logMut.Unlock() + + self.logs[id].add(logs...) + } + id = self.filterManager.InstallFilter(filter) + self.logs[id] = &logFilter{timeout: time.Now()} + + return id +} + +func (self *XEth) UninstallFilter(id int) bool { + if _, ok := self.logs[id]; ok { + delete(self.logs, id) + self.filterManager.UninstallFilter(id) + return true + } + + return false +} + +func (self *XEth) NewFilterString(word string) int { + var id int + filter := core.NewFilter(self.Backend()) + + callback := func(block *types.Block, logs state.Logs) { + self.logMut.Lock() + defer self.logMut.Unlock() + + for _, log := range logs { + self.logs[id].add(log) + } + self.logs[id].add(&state.StateLog{}) + } + + switch word { + case "pending": + filter.PendingCallback = callback + case "latest": + filter.BlockCallback = callback + } + + id = self.filterManager.InstallFilter(filter) + self.logs[id] = &logFilter{timeout: time.Now()} + + return id +} + +func (self *XEth) FilterChanged(id int) state.Logs { + self.logMut.Lock() + defer self.logMut.Unlock() + + if self.logs[id] != nil { + return self.logs[id].get() + } + + return nil +} + +func (self *XEth) Logs(id int) state.Logs { + self.logMut.Lock() + defer self.logMut.Unlock() + + filter := self.filterManager.GetFilter(id) + if filter != nil { + return filter.Find() + } + + return nil +} + +func (self *XEth) AllLogs(args *core.FilterOptions) state.Logs { + filter := core.NewFilter(self.Backend()) + filter.SetOptions(args) + + return filter.Find() +} + +func (p *XEth) NewWhisperFilter(opts *Options) int { + var id int + opts.Fn = func(msg WhisperMessage) { + p.messagesMut.Lock() + defer p.messagesMut.Unlock() + p.messages[id].add(msg) // = append(p.messages[id], msg) + } + id = p.Whisper().Watch(opts) + p.messages[id] = &whisperFilter{timeout: time.Now()} + return id +} + +func (p *XEth) UninstallWhisperFilter(id int) bool { + if _, ok := p.messages[id]; ok { + delete(p.messages, id) + return true + } + + return false +} + +func (self *XEth) MessagesChanged(id int) []WhisperMessage { + self.messagesMut.Lock() + defer self.messagesMut.Unlock() + + if self.messages[id] != nil { + return self.messages[id].get() + } + + return nil +} + type KeyVal struct { Key string `json:"key"` Value string `json:"value"` @@ -411,3 +581,36 @@ func (m callmsg) GasPrice() *big.Int { return m.gasPrice } func (m callmsg) Gas() *big.Int { return m.gas } func (m callmsg) Value() *big.Int { return m.value } func (m callmsg) Data() []byte { return m.data } + +type whisperFilter struct { + messages []WhisperMessage + timeout time.Time + id int +} + +func (w *whisperFilter) add(msgs ...WhisperMessage) { + w.messages = append(w.messages, msgs...) +} +func (w *whisperFilter) get() []WhisperMessage { + w.timeout = time.Now() + tmp := w.messages + w.messages = nil + return tmp +} + +type logFilter struct { + logs state.Logs + timeout time.Time + id int +} + +func (l *logFilter) add(logs ...state.Log) { + l.logs = append(l.logs, logs...) +} + +func (l *logFilter) get() state.Logs { + l.timeout = time.Now() + tmp := l.logs + l.logs = nil + return tmp +} From 4663a55f123c3d4886a0537243d1ad86d2a51f21 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:03:53 -0400 Subject: [PATCH 26/51] inline NewFilter --- rpc/api.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 9a994ebbd6..495771a59c 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -98,14 +98,6 @@ func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { // return nil // } -func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error { - opts := toFilterOptions(args) - id := self.xeth().RegisterFilter(opts) - *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) - - return nil -} - func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error { *reply = self.xeth().UninstallFilter(id) @@ -491,7 +483,10 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.NewFilter(args, reply) + + opts := toFilterOptions(args) + id := p.xeth().RegisterFilter(opts) + *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) case "eth_newBlockFilter": args := new(FilterStringArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 84b19971fadaae6d4b77667327d967f62d8726f8 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:05:23 -0400 Subject: [PATCH 27/51] inline UninstallFilter --- rpc/api.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 495771a59c..2dd171a652 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -98,12 +98,6 @@ func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { // return nil // } -func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error { - *reply = self.xeth().UninstallFilter(id) - - return nil -} - func (self *EthereumApi) NewFilterString(args *FilterStringArgs, reply *interface{}) error { if err := args.requirements(); err != nil { return err @@ -498,7 +492,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.UninstallFilter(args.Id, reply) + *reply = p.xeth().UninstallFilter(args.Id) case "eth_getFilterChanges": args := new(FilterIdArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 3e9632e2566d9853e4c12ccd545e818df290219b Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:06:32 -0400 Subject: [PATCH 28/51] inline NewFilterString --- rpc/api.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 2dd171a652..39137d8db3 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -98,16 +98,6 @@ func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { // return nil // } -func (self *EthereumApi) NewFilterString(args *FilterStringArgs, reply *interface{}) error { - if err := args.requirements(); err != nil { - return err - } - - id := self.xeth().NewFilterString(args.Word) - *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) - return nil -} - func (self *EthereumApi) FilterChanged(id int, reply *interface{}) error { *reply = NewLogsRes(self.xeth().FilterChanged(id)) return nil @@ -486,7 +476,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.NewFilterString(args, reply) + if err := args.requirements(); err != nil { + return err + } + + id := p.xeth().NewFilterString(args.Word) + *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) case "eth_uninstallFilter": args := new(FilterIdArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From d2e741423057c483522f5eaa1daece72aab2ee43 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:07:25 -0400 Subject: [PATCH 29/51] inline FilterChanged --- rpc/api.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 39137d8db3..d6e9dc1b1e 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -98,11 +98,6 @@ func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { // return nil // } -func (self *EthereumApi) FilterChanged(id int, reply *interface{}) error { - *reply = NewLogsRes(self.xeth().FilterChanged(id)) - return nil -} - func (self *EthereumApi) Logs(id int, reply *interface{}) error { *reply = NewLogsRes(self.xeth().Logs(id)) @@ -493,7 +488,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.FilterChanged(args.Id, reply) + *reply = NewLogsRes(p.xeth().FilterChanged(args.Id)) case "eth_getFilterLogs": args := new(FilterIdArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 0bda63eb76755574750112252457931719515a71 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:08:26 -0400 Subject: [PATCH 30/51] inline Logs --- rpc/api.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index d6e9dc1b1e..a472229a4c 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -98,12 +98,6 @@ func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { // return nil // } -func (self *EthereumApi) Logs(id int, reply *interface{}) error { - *reply = NewLogsRes(self.xeth().Logs(id)) - - return nil -} - func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error { opts := toFilterOptions(args) *reply = NewLogsRes(self.xeth().AllLogs(opts)) @@ -494,7 +488,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.Logs(args.Id, reply) + *reply = NewLogsRes(p.xeth().Logs(args.Id)) case "eth_getLogs": args := new(FilterOptions) if err := json.Unmarshal(req.Params, &args); err != nil { From 4b5e5926560df601e3055f3cfbf120ff2f4a49cc Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:10:23 -0400 Subject: [PATCH 31/51] inline AllLogs --- rpc/api.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index a472229a4c..ff2ae6c340 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -98,13 +98,6 @@ func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { // return nil // } -func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error { - opts := toFilterOptions(args) - *reply = NewLogsRes(self.xeth().AllLogs(opts)) - - return nil -} - func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) (err error) { // TODO if no_private_key then //if _, exists := p.register[args.From]; exists { @@ -494,7 +487,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.AllLogs(args, reply) + opts := toFilterOptions(args) + *reply = NewLogsRes(p.xeth().AllLogs(opts)) case "eth_getWork", "eth_submitWork": return NewNotImplementedError(req.Method) case "db_putString": From 1f9b93647be5badfec854210b6c2b036d8c9aa6c Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:11:52 -0400 Subject: [PATCH 32/51] inline NewWhisperFilter --- rpc/api.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index ff2ae6c340..15a9f8b1f5 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -175,16 +175,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) NewWhisperFilter(args *WhisperFilterArgs, reply *interface{}) error { - opts := new(xeth.Options) - opts.From = args.From - opts.To = args.To - opts.Topics = args.Topics - id := p.xeth().NewWhisperFilter(opts) - *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) - return nil -} - func (p *EthereumApi) UninstallWhisperFilter(id int, reply *interface{}) error { *reply = p.xeth().UninstallWhisperFilter(id) return nil @@ -550,7 +540,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.NewWhisperFilter(args, reply) + opts := new(xeth.Options) + opts.From = args.From + opts.To = args.To + opts.Topics = args.Topics + id := p.xeth().NewWhisperFilter(opts) + *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) case "shh_uninstallFilter": args := new(FilterIdArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 2ef2b9f2e011d482a50456da91ad4b7a4be57841 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:13:52 -0400 Subject: [PATCH 33/51] inline UninstallWhisperFilter --- rpc/api.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 15a9f8b1f5..1d4e737b51 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -175,11 +175,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) UninstallWhisperFilter(id int, reply *interface{}) error { - *reply = p.xeth().UninstallWhisperFilter(id) - return nil -} - func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { *reply = self.xeth().MessagesChanged(id) return nil @@ -551,8 +546,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - - return p.UninstallWhisperFilter(args.Id, reply) + *reply = p.xeth().UninstallWhisperFilter(args.Id) case "shh_getFilterChanges": args := new(FilterIdArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 7b45f3377f3f8d911d7678530138a1249f523155 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:14:55 -0400 Subject: [PATCH 34/51] inline MessagesChanged --- rpc/api.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 1d4e737b51..8e3d3cc63f 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -175,11 +175,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { - *reply = self.xeth().MessagesChanged(id) - return nil -} - func (p *EthereumApi) GetBlockByHash(blockhash string, includetx bool) (*BlockRes, error) { block := p.xeth().EthBlockByHash(blockhash) br := NewBlockRes(block) @@ -552,7 +547,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.MessagesChanged(args.Id, reply) + *reply = p.xeth().MessagesChanged(args.Id) case "shh_getMessages": args := new(FilterIdArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 6669ef5b701f8b060287c8a63e9f3c1116b4b74a Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:20:54 -0400 Subject: [PATCH 35/51] Rename for clarity --- rpc/api.go | 18 +++++++++--------- rpc/args.go | 12 ++++++------ rpc/args_test.go | 12 ++++++------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 8e3d3cc63f..06014c74ff 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -46,6 +46,13 @@ func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi { return api } +func (self *EthereumApi) xeth() *xeth.XEth { + self.xethMu.RLock() + defer self.xethMu.RUnlock() + + return self.eth +} + func (self *EthereumApi) xethWithStateNum(num int64) *xeth.XEth { chain := self.xeth().Backend().ChainManager() var block *types.Block @@ -328,7 +335,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockByHash(args.BlockHash, args.Transactions) + v, err := p.GetBlockByHash(args.BlockHash, args.IncludeTxs) if err != nil { return err } @@ -339,7 +346,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockByNumber(args.BlockNumber, args.Transactions) + v, err := p.GetBlockByNumber(args.BlockNumber, args.IncludeTxs) if err != nil { return err } @@ -580,13 +587,6 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return nil } -func (self *EthereumApi) xeth() *xeth.XEth { - self.xethMu.RLock() - defer self.xethMu.RUnlock() - - return self.eth -} - func toFilterOptions(options *FilterOptions) *core.FilterOptions { var opts core.FilterOptions diff --git a/rpc/args.go b/rpc/args.go index bd6be5a0f3..cbb199902e 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -35,8 +35,8 @@ func blockAge(raw interface{}, number *int64) (err error) { } type GetBlockByHashArgs struct { - BlockHash string - Transactions bool + BlockHash string + IncludeTxs bool } func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) { @@ -57,15 +57,15 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) { args.BlockHash = argstr if len(obj) > 1 { - args.Transactions = obj[1].(bool) + args.IncludeTxs = obj[1].(bool) } return nil } type GetBlockByNumberArgs struct { - BlockNumber int64 - Transactions bool + BlockNumber int64 + IncludeTxs bool } func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { @@ -86,7 +86,7 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { } if len(obj) > 1 { - args.Transactions = obj[1].(bool) + args.IncludeTxs = obj[1].(bool) } return nil diff --git a/rpc/args_test.go b/rpc/args_test.go index 0d8dc4085f..f1ad6e8eda 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -82,7 +82,7 @@ func TestGetBlockByHashArgs(t *testing.T) { input := `["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]` expected := new(GetBlockByHashArgs) expected.BlockHash = "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" - expected.Transactions = true + expected.IncludeTxs = true args := new(GetBlockByHashArgs) if err := json.Unmarshal([]byte(input), &args); err != nil { @@ -93,8 +93,8 @@ func TestGetBlockByHashArgs(t *testing.T) { t.Errorf("BlockHash should be %v but is %v", expected.BlockHash, args.BlockHash) } - if args.Transactions != expected.Transactions { - t.Errorf("Transactions should be %v but is %v", expected.Transactions, args.Transactions) + if args.IncludeTxs != expected.IncludeTxs { + t.Errorf("IncludeTxs should be %v but is %v", expected.IncludeTxs, args.IncludeTxs) } } @@ -112,7 +112,7 @@ func TestGetBlockByNumberArgs(t *testing.T) { input := `["0x1b4", false]` expected := new(GetBlockByNumberArgs) expected.BlockNumber = 436 - expected.Transactions = false + expected.IncludeTxs = false args := new(GetBlockByNumberArgs) if err := json.Unmarshal([]byte(input), &args); err != nil { @@ -123,8 +123,8 @@ func TestGetBlockByNumberArgs(t *testing.T) { t.Errorf("BlockHash should be %v but is %v", expected.BlockNumber, args.BlockNumber) } - if args.Transactions != expected.Transactions { - t.Errorf("Transactions should be %v but is %v", expected.Transactions, args.Transactions) + if args.IncludeTxs != expected.IncludeTxs { + t.Errorf("IncludeTxs should be %v but is %v", expected.IncludeTxs, args.IncludeTxs) } } From 19360c00795d356d052a379663c3f36aedba3f9e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:28:45 -0400 Subject: [PATCH 36/51] Move stateAt func to XEth --- rpc/api.go | 36 ++++++------------------------------ xeth/xeth.go | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 06014c74ff..f31b9a3446 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -10,11 +10,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/xeth" ) @@ -53,28 +51,6 @@ func (self *EthereumApi) xeth() *xeth.XEth { return self.eth } -func (self *EthereumApi) xethWithStateNum(num int64) *xeth.XEth { - chain := self.xeth().Backend().ChainManager() - var block *types.Block - - if num < 0 { - num = chain.CurrentBlock().Number().Int64() + num + 1 - } - block = chain.GetBlockByNumber(uint64(num)) - - var st *state.StateDB - if block != nil { - st = state.New(block.Root(), self.xeth().Backend().StateDb()) - } else { - st = chain.State() - } - return self.xeth().WithState(st) -} - -func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { - return self.xethWithStateNum(num).State() -} - // func (self *EthereumApi) Register(args string, reply *interface{}) error { // self.regmut.Lock() // defer self.regmut.Unlock() @@ -152,7 +128,7 @@ func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) (err error) } func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error { - result, err := p.xethWithStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + result, err := p.xeth().AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { return err } @@ -166,7 +142,7 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return err } - state := p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address) + state := p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address) value := state.StorageString(args.Key) var hx string @@ -240,7 +216,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - *reply = common.ToHex(p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance().Bytes()) + *reply = common.ToHex(p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance().Bytes()) case "eth_getStorage", "eth_storageAt": args := new(GetStorageArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -251,7 +227,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - *reply = p.xethWithStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() + *reply = p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() case "eth_getStorageAt": args := new(GetStorageAtArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -269,7 +245,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - *reply = p.xethWithStateNum(args.BlockNumber).TxCountAt(args.Address) + *reply = p.xeth().AtStateNum(args.BlockNumber).TxCountAt(args.Address) case "eth_getBlockTransactionCountByHash": args := new(GetBlockByHashArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -314,7 +290,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := args.requirements(); err != nil { return err } - *reply = p.xethWithStateNum(args.BlockNumber).CodeAt(args.Address) + *reply = p.xeth().AtStateNum(args.BlockNumber).CodeAt(args.Address) case "eth_sendTransaction", "eth_transact": args := new(NewTxArgs) if err := json.Unmarshal(req.Params, &args); err != nil { diff --git a/xeth/xeth.go b/xeth/xeth.go index 922fce8f11..504a93f587 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -154,6 +154,24 @@ func (self *XEth) stop() { close(self.quit) } +func (self *XEth) AtStateNum(num int64) *XEth { + chain := self.Backend().ChainManager() + var block *types.Block + + if num < 0 { + num = chain.CurrentBlock().Number().Int64() + num + 1 + } + block = chain.GetBlockByNumber(uint64(num)) + + var st *state.StateDB + if block != nil { + st = state.New(block.Root(), self.Backend().StateDb()) + } else { + st = chain.State() + } + return self.WithState(st) +} + func (self *XEth) Backend() Backend { return self.eth } func (self *XEth) WithState(statedb *state.StateDB) *XEth { xeth := &XEth{ From d791fe4975fa62618f854a86f1648d5fe7081b79 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:34:35 -0400 Subject: [PATCH 37/51] Remove unnecessary event mux --- rpc/api.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index f31b9a3446..cef5e46898 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -12,7 +12,6 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/xeth" ) @@ -24,7 +23,6 @@ var ( type EthereumApi struct { eth *xeth.XEth xethMu sync.RWMutex - mux *event.TypeMux // // Register keeps a list of accounts and transaction data // regmut sync.Mutex @@ -34,10 +32,10 @@ type EthereumApi struct { } func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi { + // What about when dataDir is empty? db, _ := ethdb.NewLDBDatabase(path.Join(dataDir, "dapps")) api := &EthereumApi{ eth: eth, - mux: eth.Backend().EventMux(), db: db, } From 3cea7d87c1b9fadf19211fad2aece303b1677e27 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Mar 2015 23:55:17 -0400 Subject: [PATCH 38/51] Rename FilterOptions to BlockFilterArgs --- rpc/api.go | 6 +++--- rpc/args.go | 4 ++-- rpc/args_test.go | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index cef5e46898..9f0b88b48f 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -406,7 +406,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error case "eth_compileSolidity", "eth_compileLLL", "eth_compileSerpent": return NewNotImplementedError(req.Method) case "eth_newFilter": - args := new(FilterOptions) + args := new(BlockFilterArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } @@ -444,7 +444,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error } *reply = NewLogsRes(p.xeth().Logs(args.Id)) case "eth_getLogs": - args := new(FilterOptions) + args := new(BlockFilterArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } @@ -561,7 +561,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return nil } -func toFilterOptions(options *FilterOptions) *core.FilterOptions { +func toFilterOptions(options *BlockFilterArgs) *core.FilterOptions { var opts core.FilterOptions // Convert optional address slice/string to byte slice diff --git a/rpc/args.go b/rpc/args.go index cbb199902e..e50c9b1f5b 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -433,7 +433,7 @@ func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) { return nil } -type FilterOptions struct { +type BlockFilterArgs struct { Earliest int64 Latest int64 Address interface{} @@ -442,7 +442,7 @@ type FilterOptions struct { Max int } -func (args *FilterOptions) UnmarshalJSON(b []byte) (err error) { +func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { var obj []struct { FromBlock interface{} `json:"fromBlock"` ToBlock interface{} `json:"toBlock"` diff --git a/rpc/args_test.go b/rpc/args_test.go index f1ad6e8eda..cfdd278b8f 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -388,7 +388,7 @@ func TestGetDataEmptyArgs(t *testing.T) { } } -func TestFilterOptions(t *testing.T) { +func TestBlockFilterArgs(t *testing.T) { input := `[{ "fromBlock": "0x1", "toBlock": "0x2", @@ -396,7 +396,7 @@ func TestFilterOptions(t *testing.T) { "offset": "0x0", "address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", "topics": ["0x12341234"]}]` - expected := new(FilterOptions) + expected := new(BlockFilterArgs) expected.Earliest = 1 expected.Latest = 2 expected.Max = 3 @@ -404,7 +404,7 @@ func TestFilterOptions(t *testing.T) { expected.Address = "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8" // expected.Topics = []string{"0x12341234"} - args := new(FilterOptions) + args := new(BlockFilterArgs) if err := json.Unmarshal([]byte(input), &args); err != nil { t.Error(err) } @@ -434,16 +434,16 @@ func TestFilterOptions(t *testing.T) { // } } -func TestFilterOptionsWords(t *testing.T) { +func TestBlockFilterArgsWords(t *testing.T) { input := `[{ "fromBlock": "latest", "toBlock": "pending" }]` - expected := new(FilterOptions) + expected := new(BlockFilterArgs) expected.Earliest = 0 expected.Latest = -1 - args := new(FilterOptions) + args := new(BlockFilterArgs) if err := json.Unmarshal([]byte(input), &args); err != nil { t.Error(err) } @@ -457,13 +457,13 @@ func TestFilterOptionsWords(t *testing.T) { } } -func TestFilterOptionsNums(t *testing.T) { +func TestBlockFilterArgsNums(t *testing.T) { input := `[{ "fromBlock": 2, "toBlock": 3 }]` - args := new(FilterOptions) + args := new(BlockFilterArgs) err := json.Unmarshal([]byte(input), &args) switch err.(type) { case *DecodeParamError: @@ -474,10 +474,10 @@ func TestFilterOptionsNums(t *testing.T) { } -func TestFilterOptionsEmptyArgs(t *testing.T) { +func TestBlockFilterArgsEmptyArgs(t *testing.T) { input := `[]` - args := new(FilterOptions) + args := new(BlockFilterArgs) err := json.Unmarshal([]byte(input), &args) if err == nil { t.Error("Expected error but didn't get one") From c3a3d387352cf9cf626dc67e0aeaaa68c4bc651a Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 00:08:29 -0400 Subject: [PATCH 39/51] Add tests for errors --- rpc/messages_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 rpc/messages_test.go diff --git a/rpc/messages_test.go b/rpc/messages_test.go new file mode 100644 index 0000000000..5274c91e42 --- /dev/null +++ b/rpc/messages_test.go @@ -0,0 +1,41 @@ +package rpc + +import ( + "testing" +) + +func TestInsufficientParamsError(t *testing.T) { + err := NewInsufficientParamsError(0, 1) + expected := "insufficient params, want 1 have 0" + + if err.Error() != expected { + t.Error(err.Error()) + } +} + +func TestNotImplementedError(t *testing.T) { + err := NewNotImplementedError("foo") + expected := "foo method not implemented" + + if err.Error() != expected { + t.Error(err.Error()) + } +} + +func TestDecodeParamError(t *testing.T) { + err := NewDecodeParamError("foo") + expected := "could not decode, foo" + + if err.Error() != expected { + t.Error(err.Error()) + } +} + +func TestValidationError(t *testing.T) { + err := NewValidationError("foo", "should be `bar`") + expected := "foo not valid, should be `bar`" + + if err.Error() != expected { + t.Error(err.Error()) + } +} From 754160afea7fc230c3236d5494beefeb03b94140 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 00:23:48 -0400 Subject: [PATCH 40/51] Move gas defaults to XEth --- rpc/api.go | 13 +++---------- xeth/xeth.go | 10 +++++----- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 9f0b88b48f..1626fd0afc 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -2,7 +2,6 @@ package rpc import ( "encoding/json" - "fmt" "math/big" "path" "strings" @@ -15,11 +14,6 @@ import ( "github.com/ethereum/go-ethereum/xeth" ) -var ( - defaultGasPrice = big.NewInt(150000000000) - defaultGas = big.NewInt(500000) -) - type EthereumApi struct { eth *xeth.XEth xethMu sync.RWMutex @@ -109,16 +103,15 @@ func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) (err error) // TODO: align default values to have the same type, e.g. not depend on // common.Value conversions later on if args.Gas.Cmp(big.NewInt(0)) == 0 { - args.Gas = defaultGas + args.Gas = p.xeth().DefaultGas() } if args.GasPrice.Cmp(big.NewInt(0)) == 0 { - args.GasPrice = defaultGasPrice + args.GasPrice = p.xeth().DefaultGasPrice() } *reply, err = p.xeth().Transact(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { - fmt.Println("err:", err) return err } @@ -199,7 +192,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error case "eth_mining": *reply = p.xeth().IsMining() case "eth_gasPrice": - *reply = common.ToHex(defaultGasPrice.Bytes()) + *reply = common.ToHex(p.xeth().DefaultGas().Bytes()) case "eth_accounts": *reply = p.xeth().Accounts() case "eth_blockNumber": diff --git a/xeth/xeth.go b/xeth/xeth.go index 504a93f587..690db51350 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -25,6 +25,8 @@ import ( var ( pipelogger = logger.NewLogger("XETH") filterTickerTime = 5 * time.Minute + defaultGasPrice = big.NewInt(10000000000000) //150000000000 + defaultGas = big.NewInt(90000) //500000 ) // to resolve the import cycle @@ -154,6 +156,9 @@ func (self *XEth) stop() { close(self.quit) } +func (self *XEth) DefaultGas() *big.Int { return defaultGas } +func (self *XEth) DefaultGasPrice() *big.Int { return defaultGasPrice } + func (self *XEth) AtStateNum(num int64) *XEth { chain := self.Backend().ChainManager() var block *types.Block @@ -486,11 +491,6 @@ func (self *XEth) PushTx(encodedTx string) (string, error) { return common.ToHex(tx.Hash()), nil } -var ( - defaultGasPrice = big.NewInt(10000000000000) - defaultGas = big.NewInt(90000) -) - func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) { statedb := self.State().State() //self.chainManager.TransState() msg := callmsg{ From b56e20be2760343147f72ca62a8db8bd216903bf Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 00:24:23 -0400 Subject: [PATCH 41/51] Reorg for clarity --- rpc/api.go | 82 +++++++++++++++++++--------------------------------- xeth/xeth.go | 36 ++++++++++++++++++----- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 1626fd0afc..fccc7f2a4f 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -43,59 +43,7 @@ func (self *EthereumApi) xeth() *xeth.XEth { return self.eth } -// func (self *EthereumApi) Register(args string, reply *interface{}) error { -// self.regmut.Lock() -// defer self.regmut.Unlock() - -// if _, ok := self.register[args]; ok { -// self.register[args] = nil // register with empty -// } -// return nil -// } - -// func (self *EthereumApi) Unregister(args string, reply *interface{}) error { -// self.regmut.Lock() -// defer self.regmut.Unlock() - -// delete(self.register, args) - -// return nil -// } - -// func (self *EthereumApi) WatchTx(args string, reply *interface{}) error { -// self.regmut.Lock() -// defer self.regmut.Unlock() - -// txs := self.register[args] -// self.register[args] = nil - -// *reply = txs -// return nil -// } - func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) (err error) { - // TODO if no_private_key then - //if _, exists := p.register[args.From]; exists { - // p.register[args.From] = append(p.register[args.From], args) - //} else { - /* - account := accounts.Get(common.FromHex(args.From)) - if account != nil { - if account.Unlocked() { - if !unlockAccount(account) { - return - } - } - - result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data)) - if len(result) > 0 { - *reply = common.ToHex(result) - } - } else if _, exists := p.register[args.From]; exists { - p.register[ags.From] = append(p.register[args.From], args) - } - */ - if err := args.requirements(); err != nil { return err } @@ -163,6 +111,36 @@ func (p *EthereumApi) GetBlockByNumber(blocknum int64, includetx bool) (*BlockRe return br, nil } +// func (self *EthereumApi) Register(args string, reply *interface{}) error { +// self.regmut.Lock() +// defer self.regmut.Unlock() + +// if _, ok := self.register[args]; ok { +// self.register[args] = nil // register with empty +// } +// return nil +// } + +// func (self *EthereumApi) Unregister(args string, reply *interface{}) error { +// self.regmut.Lock() +// defer self.regmut.Unlock() + +// delete(self.register, args) + +// return nil +// } + +// func (self *EthereumApi) WatchTx(args string, reply *interface{}) error { +// self.regmut.Lock() +// defer self.regmut.Unlock() + +// txs := self.register[args] +// self.register[args] = nil + +// *reply = txs +// return nil +// } + func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { // Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC rpclogger.Infof("%s %s", req.Method, req.Params) diff --git a/xeth/xeth.go b/xeth/xeth.go index 690db51350..3d44e292c8 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -70,6 +70,13 @@ type Frontend interface { ConfirmTransaction(tx *types.Transaction) bool } +// dummyFrontend is a non-interactive frontend that allows all +// transactions but cannot not unlock any keys. +type dummyFrontend struct{} + +func (dummyFrontend) UnlockAccount([]byte) bool { return false } +func (dummyFrontend) ConfirmTransaction(*types.Transaction) bool { return true } + type XEth struct { eth Backend blockProcessor *core.BlockProcessor @@ -90,13 +97,6 @@ type XEth struct { messages map[int]*whisperFilter } -// dummyFrontend is a non-interactive frontend that allows all -// transactions but cannot not unlock any keys. -type dummyFrontend struct{} - -func (dummyFrontend) UnlockAccount([]byte) bool { return false } -func (dummyFrontend) ConfirmTransaction(*types.Transaction) bool { return true } - // New creates an XEth that uses the given frontend. // If a nil Frontend is provided, a default frontend which // confirms all transactions will be used. @@ -527,6 +527,28 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt contractCreation bool ) + // TODO if no_private_key then + //if _, exists := p.register[args.From]; exists { + // p.register[args.From] = append(p.register[args.From], args) + //} else { + /* + account := accounts.Get(common.FromHex(args.From)) + if account != nil { + if account.Unlocked() { + if !unlockAccount(account) { + return + } + } + + result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data)) + if len(result) > 0 { + *reply = common.ToHex(result) + } + } else if _, exists := p.register[args.From]; exists { + p.register[ags.From] = append(p.register[args.From], args) + } + */ + from = common.FromHex(fromStr) data = common.FromHex(codeStr) to = common.FromHex(toStr) From bde161382a0ce4dad9c422870e16169cfba0fcc0 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 06:53:24 +0100 Subject: [PATCH 42/51] inline GetBlockByHash --- rpc/api.go | 51 ++++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index fccc7f2a4f..3efb4c55e2 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -97,13 +97,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) GetBlockByHash(blockhash string, includetx bool) (*BlockRes, error) { - block := p.xeth().EthBlockByHash(blockhash) - br := NewBlockRes(block) - br.fullTx = includetx - return br, nil -} - func (p *EthereumApi) GetBlockByNumber(blocknum int64, includetx bool) (*BlockRes, error) { block := p.xeth().EthBlockByNumber(blocknum) br := NewBlockRes(block) @@ -280,11 +273,11 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockByHash(args.BlockHash, args.IncludeTxs) - if err != nil { - return err - } - *reply = v + block := p.xeth().EthBlockByHash(args.BlockHash) + br := NewBlockRes(block) + br.fullTx = args.IncludeTxs + + *reply = br case "eth_getBlockByNumber": args := new(GetBlockByNumberArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -311,14 +304,14 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockByHash(args.Hash, true) - if err != nil { - return err - } - if args.Index > int64(len(v.Transactions)) || args.Index < 0 { + block := p.xeth().EthBlockByHash(args.Hash) + br := NewBlockRes(block) + br.fullTx = true + + if args.Index > int64(len(br.Transactions)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } - *reply = v.Transactions[args.Index] + *reply = br.Transactions[args.Index] case "eth_getTransactionByBlockNumberAndIndex": args := new(BlockNumIndexArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -339,18 +332,15 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockByHash(args.Hash, false) - if err != nil { - return err - } - if args.Index > int64(len(v.Uncles)) || args.Index < 0 { + br := NewBlockRes(p.xeth().EthBlockByHash(args.Hash)) + + if args.Index > int64(len(br.Uncles)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } - uncle, err := p.GetBlockByHash(common.ToHex(v.Uncles[args.Index]), false) - if err != nil { - return err - } + uhash := common.ToHex(br.Uncles[args.Index]) + uncle := NewBlockRes(p.xeth().EthBlockByHash(uhash)) + *reply = uncle case "eth_getUncleByBlockNumberAndIndex": args := new(BlockNumIndexArgs) @@ -366,10 +356,9 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return NewValidationError("Index", "does not exist") } - uncle, err := p.GetBlockByHash(common.ToHex(v.Uncles[args.Index]), false) - if err != nil { - return err - } + uhash := common.ToHex(v.Uncles[args.Index]) + uncle := NewBlockRes(p.xeth().EthBlockByHash(uhash)) + *reply = uncle case "eth_getCompilers": c := []string{""} From 1d6451f5c390b13deb88d9a3878bb7d26d2797b8 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 06:57:23 +0100 Subject: [PATCH 43/51] inline GetBlockByNumber --- rpc/api.go | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 3efb4c55e2..63e2a85ddb 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -97,13 +97,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) GetBlockByNumber(blocknum int64, includetx bool) (*BlockRes, error) { - block := p.xeth().EthBlockByNumber(blocknum) - br := NewBlockRes(block) - br.fullTx = includetx - return br, nil -} - // func (self *EthereumApi) Register(args string, reply *interface{}) error { // self.regmut.Lock() // defer self.regmut.Unlock() @@ -284,11 +277,11 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockByNumber(args.BlockNumber, args.IncludeTxs) - if err != nil { - return err - } - *reply = v + block := p.xeth().EthBlockByNumber(args.BlockNumber) + br := NewBlockRes(block) + br.fullTx = args.IncludeTxs + + *reply = br case "eth_getTransactionByHash": // HashIndexArgs used, but only the "Hash" part we need. args := new(HashIndexArgs) @@ -318,10 +311,10 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockByNumber(args.BlockNumber, true) - if err != nil { - return err - } + block := p.xeth().EthBlockByNumber(args.BlockNumber) + v := NewBlockRes(block) + v.fullTx = true + if args.Index > int64(len(v.Transactions)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } @@ -348,10 +341,10 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.GetBlockByNumber(args.BlockNumber, true) - if err != nil { - return err - } + block := p.xeth().EthBlockByNumber(args.BlockNumber) + v := NewBlockRes(block) + v.fullTx = true + if args.Index > int64(len(v.Uncles)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } From e038a42d7a0e7e2c6ad7cef6c6446ad1e9454fe5 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 06:58:53 +0100 Subject: [PATCH 44/51] inline Call --- rpc/api.go | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 63e2a85ddb..0596aee481 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -66,16 +66,6 @@ func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) (err error) return nil } -func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error { - result, err := p.xeth().AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) - if err != nil { - return err - } - - *reply = result - return nil -} - func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) error { if err := args.requirements(); err != nil { return err @@ -257,7 +247,13 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.Call(args, reply) + + result, err := p.xeth().AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + if err != nil { + return err + } + + *reply = result case "eth_flush": return NewNotImplementedError(req.Method) case "eth_getBlockByHash": From aa3918efa711a51c241a70d675b27fc0f0c01ec3 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 07:13:29 +0100 Subject: [PATCH 45/51] Move transact gas check to XEth --- rpc/api.go | 10 ---------- xeth/xeth.go | 18 ++++++++++++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 0596aee481..20b586686d 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -48,16 +48,6 @@ func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) (err error) return err } - // TODO: align default values to have the same type, e.g. not depend on - // common.Value conversions later on - if args.Gas.Cmp(big.NewInt(0)) == 0 { - args.Gas = p.xeth().DefaultGas() - } - - if args.GasPrice.Cmp(big.NewInt(0)) == 0 { - args.GasPrice = p.xeth().DefaultGasPrice() - } - *reply, err = p.xeth().Transact(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { return err diff --git a/xeth/xeth.go b/xeth/xeth.go index 3d44e292c8..e1e25ba09f 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -521,8 +521,8 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt from []byte to []byte value = common.NewValue(valueStr) - gas = common.NewValue(gasStr) - price = common.NewValue(gasPriceStr) + gas = common.Big(gasStr) + price = common.Big(gasPriceStr) data []byte contractCreation bool ) @@ -549,6 +549,16 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt } */ + // TODO: align default values to have the same type, e.g. not depend on + // common.Value conversions later on + if gas.Cmp(big.NewInt(0)) == 0 { + gas = defaultGas + } + + if price.Cmp(big.NewInt(0)) == 0 { + price = defaultGasPrice + } + from = common.FromHex(fromStr) data = common.FromHex(codeStr) to = common.FromHex(toStr) @@ -558,9 +568,9 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt var tx *types.Transaction if contractCreation { - tx = types.NewContractCreationTx(value.BigInt(), gas.BigInt(), price.BigInt(), data) + tx = types.NewContractCreationTx(value.BigInt(), gas, price, data) } else { - tx = types.NewTransactionMessage(to, value.BigInt(), gas.BigInt(), price.BigInt(), data) + tx = types.NewTransactionMessage(to, value.BigInt(), gas, price, data) } state := self.chainManager.TxState() From b3329bc698722881b636af882df67eff79822da4 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 07:15:34 +0100 Subject: [PATCH 46/51] inline Transact --- rpc/api.go | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 20b586686d..3b60d661b9 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -43,19 +43,6 @@ func (self *EthereumApi) xeth() *xeth.XEth { return self.eth } -func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) (err error) { - if err := args.requirements(); err != nil { - return err - } - - *reply, err = p.xeth().Transact(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) - if err != nil { - return err - } - - return nil -} - func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) error { if err := args.requirements(); err != nil { return err @@ -231,7 +218,16 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.Transact(args, reply) + + if err := args.requirements(); err != nil { + return err + } + + v, err := p.xeth().Transact(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + if err != nil { + return err + } + *reply = v case "eth_call": args := new(NewTxArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From 55fdf3e46272ec50a4d55f519b542df790920306 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Mar 2015 12:07:06 +0100 Subject: [PATCH 47/51] Listen to tx pre event and trigger 'pending' --- core/filter.go | 2 +- event/filter/eth_filter.go | 7 ++++--- rpc/api.go | 27 +++++++++++++++------------ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/core/filter.go b/core/filter.go index 487e82902e..0aebcbf69f 100644 --- a/core/filter.go +++ b/core/filter.go @@ -34,7 +34,7 @@ type Filter struct { topics [][][]byte BlockCallback func(*types.Block, state.Logs) - PendingCallback func(*types.Block, state.Logs) + PendingCallback func(*types.Transaction) LogsCallback func(state.Logs) } diff --git a/event/filter/eth_filter.go b/event/filter/eth_filter.go index cb75d7e1a0..ab811e90e6 100644 --- a/event/filter/eth_filter.go +++ b/event/filter/eth_filter.go @@ -62,8 +62,9 @@ func (self *FilterManager) GetFilter(id int) *core.Filter { func (self *FilterManager) filterLoop() { // Subscribe to events events := self.eventMux.Subscribe( - core.PendingBlockEvent{}, + //core.PendingBlockEvent{}, core.ChainEvent{}, + core.TxPreEvent{}, state.Logs(nil)) out: @@ -82,11 +83,11 @@ out: } self.filterMu.RUnlock() - case core.PendingBlockEvent: + case core.TxPreEvent: self.filterMu.RLock() for _, filter := range self.filters { if filter.PendingCallback != nil { - filter.PendingCallback(event.Block, event.Logs) + filter.PendingCallback(event.Tx) } } self.filterMu.RUnlock() diff --git a/rpc/api.go b/rpc/api.go index afc0bd4556..fcf2ac9dc2 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -180,21 +180,24 @@ func (self *EthereumApi) NewFilterString(args *FilterStringArgs, reply *interfac var id int filter := core.NewFilter(self.xeth().Backend()) - callback := func(block *types.Block, logs state.Logs) { - self.logMut.Lock() - defer self.logMut.Unlock() - - for _, log := range logs { - self.logs[id].add(log) - } - self.logs[id].add(&state.StateLog{}) - } - switch args.Word { case "pending": - filter.PendingCallback = callback + filter.PendingCallback = func(tx *types.Transaction) { + self.logMut.Lock() + defer self.logMut.Unlock() + + self.logs[id].add(&state.StateLog{}) + } case "latest": - filter.BlockCallback = callback + filter.BlockCallback = func(block *types.Block, logs state.Logs) { + self.logMut.Lock() + defer self.logMut.Unlock() + + for _, log := range logs { + self.logs[id].add(log) + } + self.logs[id].add(&state.StateLog{}) + } default: return NewValidationError("Word", "Must be `latest` or `pending`") } From 28e5fc83526af17a911eece6befa5fe54578fb55 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 13:37:56 +0100 Subject: [PATCH 48/51] Make pretty --- rpc/api.go | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 3b60d661b9..5f29886e0d 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -111,7 +111,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error case "net_listening": *reply = p.xeth().IsListening() case "net_peerCount": - *reply = common.ToHex(big.NewInt(int64(p.xeth().PeerCount())).Bytes()) + v := p.xeth().PeerCount() + *reply = common.ToHex(big.NewInt(int64(v)).Bytes()) case "eth_coinbase": // TODO handling of empty coinbase due to lack of accounts res := p.xeth().Coinbase() @@ -123,11 +124,13 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error case "eth_mining": *reply = p.xeth().IsMining() case "eth_gasPrice": - *reply = common.ToHex(p.xeth().DefaultGas().Bytes()) + v := p.xeth().DefaultGas() + *reply = common.ToHex(v.Bytes()) case "eth_accounts": *reply = p.xeth().Accounts() case "eth_blockNumber": - *reply = common.ToHex(p.xeth().Backend().ChainManager().CurrentBlock().Number().Bytes()) + v := p.xeth().Backend().ChainManager().CurrentBlock().Number() + *reply = common.ToHex(v.Bytes()) case "eth_getBalance": args := new(GetBalanceArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -138,7 +141,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - *reply = common.ToHex(p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance().Bytes()) + v := p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance() + *reply = common.ToHex(v.Bytes()) case "eth_getStorage", "eth_storageAt": args := new(GetStorageArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -174,18 +178,16 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - block := p.xeth().EthBlockByHash(args.BlockHash) - br := NewBlockRes(block) - *reply = common.ToHex(big.NewInt(int64(len(br.Transactions))).Bytes()) + block := NewBlockRes(p.xeth().EthBlockByHash(args.BlockHash)) + *reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes()) case "eth_getBlockTransactionCountByNumber": args := new(GetBlockByNumberArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } - block := p.xeth().EthBlockByNumber(args.BlockNumber) - br := NewBlockRes(block) - *reply = common.ToHex(big.NewInt(int64(len(br.Transactions))).Bytes()) + block := NewBlockRes(p.xeth().EthBlockByNumber(args.BlockNumber)) + *reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes()) case "eth_getUncleCountByBlockHash": args := new(GetBlockByHashArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -234,12 +236,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - result, err := p.xeth().AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + v, err := p.xeth().AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { return err } - *reply = result + *reply = v case "eth_flush": return NewNotImplementedError(req.Method) case "eth_getBlockByHash": From 739c36ad4df63580bef241a4da8d2cc5010eab54 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 13:45:07 +0100 Subject: [PATCH 49/51] inline GetStorageAt --- rpc/api.go | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 5f29886e0d..4758363d1a 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -4,7 +4,6 @@ import ( "encoding/json" "math/big" "path" - "strings" "sync" "github.com/ethereum/go-ethereum/common" @@ -43,27 +42,6 @@ func (self *EthereumApi) xeth() *xeth.XEth { return self.eth } -func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) error { - if err := args.requirements(); err != nil { - return err - } - - state := p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address) - value := state.StorageString(args.Key) - - var hx string - if strings.Index(args.Key, "0x") == 0 { - hx = string([]byte(args.Key)[2:]) - } else { - // Convert the incoming string (which is a bigint) into hex - i, _ := new(big.Int).SetString(args.Key, 10) - hx = common.Bytes2Hex(i.Bytes()) - } - rpclogger.Debugf("GetStateAt(%s, %s)\n", args.Address, hx) - *reply = map[string]string{args.Key: value.Str()} - return nil -} - // func (self *EthereumApi) Register(args string, reply *interface{}) error { // self.regmut.Lock() // defer self.regmut.Unlock() @@ -159,7 +137,14 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.GetStorageAt(args, reply) + if err := args.requirements(); err != nil { + return err + } + + state := p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address) + value := state.StorageString(args.Key) + + *reply = common.Bytes2Hex(value.Bytes()) case "eth_getTransactionCount": args := new(GetTxCountArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From efcc93e7da9f47b99fc9252dc741b20086aeb4b2 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 14:12:07 +0100 Subject: [PATCH 50/51] Move Account register to xeth --- rpc/api.go | 58 +++++++++++----------------------------------------- xeth/xeth.go | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 4758363d1a..87cf42ff5a 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -16,12 +16,7 @@ import ( type EthereumApi struct { eth *xeth.XEth xethMu sync.RWMutex - - // // Register keeps a list of accounts and transaction data - // regmut sync.Mutex - // register map[string][]*NewTxArgs - - db common.Database + db common.Database } func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi { @@ -42,39 +37,9 @@ func (self *EthereumApi) xeth() *xeth.XEth { return self.eth } -// func (self *EthereumApi) Register(args string, reply *interface{}) error { -// self.regmut.Lock() -// defer self.regmut.Unlock() - -// if _, ok := self.register[args]; ok { -// self.register[args] = nil // register with empty -// } -// return nil -// } - -// func (self *EthereumApi) Unregister(args string, reply *interface{}) error { -// self.regmut.Lock() -// defer self.regmut.Unlock() - -// delete(self.register, args) - -// return nil -// } - -// func (self *EthereumApi) WatchTx(args string, reply *interface{}) error { -// self.regmut.Lock() -// defer self.regmut.Unlock() - -// txs := self.register[args] -// self.register[args] = nil - -// *reply = txs -// return nil -// } - func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { // Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC - rpclogger.Infof("%s %s", req.Method, req.Params) + rpclogger.DebugDetailf("%s %s", req.Method, req.Params) switch req.Method { case "web3_sha3": args := new(Sha3Args) @@ -458,23 +423,24 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error } *reply = p.xeth().Whisper().Messages(args.Id) // case "eth_register": - // args, err := req.ToRegisterArgs() - // if err != nil { + // // Placeholder for actual type + // args := new(HashIndexArgs) + // if err := json.Unmarshal(req.Params, &args); err != nil { // return err // } - // return p.Register(args, reply) + // *reply = p.xeth().Register(args.Hash) // case "eth_unregister": - // args, err := req.ToRegisterArgs() - // if err != nil { + // args := new(HashIndexArgs) + // if err := json.Unmarshal(req.Params, &args); err != nil { // return err // } - // return p.Unregister(args, reply) + // *reply = p.xeth().Unregister(args.Hash) // case "eth_watchTx": - // args, err := req.ToWatchTxArgs() - // if err != nil { + // args := new(HashIndexArgs) + // if err := json.Unmarshal(req.Params, &args); err != nil { // return err // } - // return p.WatchTx(args, reply) + // *reply = p.xeth().PullWatchTx(args.Hash) default: return NewNotImplementedError(req.Method) } diff --git a/xeth/xeth.go b/xeth/xeth.go index e1e25ba09f..636ee32c9a 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -95,6 +95,9 @@ type XEth struct { messagesMut sync.RWMutex messages map[int]*whisperFilter + + // regmut sync.Mutex + // register map[string][]*interface{} // TODO improve return type } // New creates an XEth that uses the given frontend. @@ -434,6 +437,39 @@ func (self *XEth) MessagesChanged(id int) []WhisperMessage { return nil } +// func (self *XEth) Register(args string) bool { +// self.regmut.Lock() +// defer self.regmut.Unlock() + +// if _, ok := self.register[args]; ok { +// self.register[args] = nil // register with empty +// } +// return true +// } + +// func (self *XEth) Unregister(args string) bool { +// self.regmut.Lock() +// defer self.regmut.Unlock() + +// if _, ok := self.register[args]; ok { +// delete(self.register, args) +// return true +// } + +// return false +// } + +// // TODO improve return type +// func (self *XEth) PullWatchTx(args string) []*interface{} { +// self.regmut.Lock() +// defer self.regmut.Unlock() + +// txs := self.register[args] +// self.register[args] = nil + +// return txs +// } + type KeyVal struct { Key string `json:"key"` Value string `json:"value"` From 0cde7a4d46f68863535fbe470499b9d0dfd6ed7a Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Mar 2015 14:56:55 +0100 Subject: [PATCH 51/51] Add xethAtStateNum convenience method --- rpc/api.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 87cf42ff5a..f318ced767 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -37,6 +37,10 @@ func (self *EthereumApi) xeth() *xeth.XEth { return self.eth } +func (self *EthereumApi) xethAtStateNum(num int64) *xeth.XEth { + return self.xeth().AtStateNum(num) +} + func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { // Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC rpclogger.DebugDetailf("%s %s", req.Method, req.Params) @@ -84,7 +88,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v := p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance() + v := p.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance() *reply = common.ToHex(v.Bytes()) case "eth_getStorage", "eth_storageAt": args := new(GetStorageArgs) @@ -96,7 +100,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - *reply = p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() + *reply = p.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() case "eth_getStorageAt": args := new(GetStorageAtArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -106,7 +110,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - state := p.xeth().AtStateNum(args.BlockNumber).State().SafeGet(args.Address) + state := p.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address) value := state.StorageString(args.Key) *reply = common.Bytes2Hex(value.Bytes()) @@ -121,7 +125,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - *reply = p.xeth().AtStateNum(args.BlockNumber).TxCountAt(args.Address) + *reply = p.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address) case "eth_getBlockTransactionCountByHash": args := new(GetBlockByHashArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -164,7 +168,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error if err := args.requirements(); err != nil { return err } - *reply = p.xeth().AtStateNum(args.BlockNumber).CodeAt(args.Address) + *reply = p.xethAtStateNum(args.BlockNumber).CodeAt(args.Address) case "eth_sendTransaction", "eth_transact": args := new(NewTxArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -186,7 +190,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } - v, err := p.xeth().AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + v, err := p.xethAtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { return err }