From 9e6785bed95a845011d88c61ee30e064787f706d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 12 Mar 2020 20:36:36 +0300 Subject: [PATCH 01/14] rpc: unify counter metrics update --- pkg/rpc/server/prometheus.go | 294 +++++++---------------------------- pkg/rpc/server/server.go | 29 +--- 2 files changed, 56 insertions(+), 267 deletions(-) diff --git a/pkg/rpc/server/prometheus.go b/pkg/rpc/server/prometheus.go index 014973daf..1a494dd70 100644 --- a/pkg/rpc/server/prometheus.go +++ b/pkg/rpc/server/prometheus.go @@ -1,249 +1,63 @@ package server -import "github.com/prometheus/client_golang/prometheus" +import ( + "fmt" + + "github.com/prometheus/client_golang/prometheus" +) // Metrics used in monitoring service. var ( - getapplicationlogCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getapplicationlog rpc endpoint", - Name: "getapplicationlog_called", - Namespace: "neogo", - }, - ) - getbestblockhashCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getbestblockhash rpc endpoint", - Name: "getbestblockhash_called", - Namespace: "neogo", - }, - ) + rpcCalls = []string{ + "getaccountstate", + "getapplicationlog", + "getassetstate", + "getbestblock", + "getbestblockhash", + "getblockcount", + "getblockhash", + "getblockheader", + "getblocksysfee", + "getclaimable", + "getconnectioncount", + "getcontractstate", + "getnep5balances", + "getnep5transfers", + "getpeers", + "getrawmempool", + "getrawtransaction", + "getstorage", + "gettransactionheight", + "gettxout", + "getunclaimed", + "getunspents", + "getvalidators", + "getversion", + "sendrawtransaction", + "submitblock", + "validateaddress", + } - getbestblockCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getbestblock rpc endpoint", - Name: "getbestblock_called", - Namespace: "neogo", - }, - ) - - getblockcountCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getblockcount rpc endpoint", - Name: "getblockcount_called", - Namespace: "neogo", - }, - ) - - getblockHashCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getblockhash rpc endpoint", - Name: "getblockhash_called", - Namespace: "neogo", - }, - ) - - getblockheaderCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getblockheader rpc endpoint", - Name: "getblockheader_called", - Namespace: "neogo", - }, - ) - - getblocksysfeeCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getblocksysfee rpc endpoint", - Name: "getblocksysfee_called", - Namespace: "neogo", - }, - ) - - getclaimableCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getclaimable rpc endpoint", - Name: "getclaimable_called", - Namespace: "neogo", - }, - ) - - getconnectioncountCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getconnectioncount rpc endpoint", - Name: "getconnectioncount_called", - Namespace: "neogo", - }, - ) - - getcontractstateCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getcontractstate rpc endpoint", - Name: "getcontractstate_called", - Namespace: "neogo", - }, - ) - getvalidatorsCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getvalidators rpc endpoint", - Name: "getvalidators_called", - Namespace: "neogo", - }, - ) - - getnep5balancesCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getnep5balances rpc endpoint", - Name: "getnep5balances_called", - Namespace: "neogo", - }, - ) - - getnep5transfersCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getnep5transfers rpc endpoint", - Name: "getnep5transfers_called", - Namespace: "neogo", - }, - ) - - getversionCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getversion rpc endpoint", - Name: "getversion_called", - Namespace: "neogo", - }, - ) - - getpeersCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getpeers rpc endpoint", - Name: "getpeers_called", - Namespace: "neogo", - }, - ) - - getrawmempoolCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getrawmempool rpc endpoint", - Name: "getrawmempool_called", - Namespace: "neogo", - }, - ) - - validateaddressCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to validateaddress rpc endpoint", - Name: "validateaddress_called", - Namespace: "neogo", - }, - ) - - getassetstateCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getassetstate rpc endpoint", - Name: "getassetstate_called", - Namespace: "neogo", - }, - ) - - getaccountstateCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getaccountstate rpc endpoint", - Name: "getaccountstate_called", - Namespace: "neogo", - }, - ) - - gettransactionheightCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to gettransactionheight rpc endpoint", - Name: "gettransactionheight_called", - Namespace: "neogo", - }, - ) - - gettxoutCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to gettxout rpc endpoint", - Name: "gettxout_called", - Namespace: "neogo", - }, - ) - - getrawtransactionCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getrawtransaction rpc endpoint", - Name: "getrawtransaction_called", - Namespace: "neogo", - }, - ) - - getunclaimedCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getunclaimed rpc endpoint", - Name: "getunclaimed_called", - Namespace: "neogo", - }, - ) - - getunspentsCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getunspents rpc endpoint", - Name: "getunspents_called", - Namespace: "neogo", - }, - ) - - sendrawtransactionCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to sendrawtransaction rpc endpoint", - Name: "sendrawtransaction_called", - Namespace: "neogo", - }, - ) - - submitblockCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to submitblock rpc endpoint", - Name: "submitblock_called", - Namespace: "neogo", - }, - ) - - getstorageCalled = prometheus.NewCounter( - prometheus.CounterOpts{ - Help: "Number of calls to getstorage rpc endpoint", - Name: "getstorage_called", - Namespace: "neogo", - }, - ) + rpcCounter = map[string]prometheus.Counter{} ) -func init() { - prometheus.MustRegister( - getapplicationlogCalled, - getbestblockhashCalled, - getbestblockCalled, - getblockcountCalled, - getblockHashCalled, - getblockheaderCalled, - getblocksysfeeCalled, - getconnectioncountCalled, - getcontractstateCalled, - getvalidatorsCalled, - getversionCalled, - getpeersCalled, - getrawmempoolCalled, - validateaddressCalled, - getassetstateCalled, - getaccountstateCalled, - getunclaimedCalled, - getunspentsCalled, - gettransactionheightCalled, - gettxoutCalled, - getrawtransactionCalled, - sendrawtransactionCalled, - submitblockCalled, - getstorageCalled, - ) +func incCounter(name string) { + ctr, ok := rpcCounter[name] + if ok { + ctr.Inc() + } +} + +func init() { + for i := range rpcCalls { + ctr := prometheus.NewCounter( + prometheus.CounterOpts{ + Help: fmt.Sprintf("Number of calls to %s rpc endpoint", rpcCalls[i]), + Name: fmt.Sprintf("%s_called", rpcCalls[i]), + Namespace: "neogo", + }, + ) + prometheus.MustRegister(ctr) + rpcCounter[rpcCalls[i]] = ctr + } } diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index a8291afcf..e14c8fb42 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -153,18 +153,17 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *request.In, reqParams resultsErr error ) + incCounter(req.Method) + Methods: switch req.Method { case "getapplicationlog": - getapplicationlogCalled.Inc() results, resultsErr = s.getApplicationLog(reqParams) case "getbestblockhash": - getbestblockhashCalled.Inc() results = "0x" + s.chain.CurrentBlockHash().StringLE() case "getblock": - getbestblockCalled.Inc() var hash util.Uint256 param, ok := reqParams.Value(0) @@ -208,11 +207,9 @@ Methods: } case "getblockcount": - getblockcountCalled.Inc() results = s.chain.BlockHeight() + 1 case "getblockhash": - getblockHashCalled.Inc() param, ok := reqParams.ValueWithType(0, request.NumberT) if !ok { resultsErr = response.ErrInvalidParams @@ -227,34 +224,26 @@ Methods: results = s.chain.GetHeaderHash(num) case "getblockheader": - getblockheaderCalled.Inc() results, resultsErr = s.getBlockHeader(reqParams) case "getblocksysfee": - getblocksysfeeCalled.Inc() results, resultsErr = s.getBlockSysFee(reqParams) case "getclaimable": - getclaimableCalled.Inc() results, resultsErr = s.getClaimable(reqParams) case "getconnectioncount": - getconnectioncountCalled.Inc() results = s.coreServer.PeerCount() case "getnep5balances": - getnep5balancesCalled.Inc() results, resultsErr = s.getNEP5Balances(reqParams) case "getnep5transfers": - getnep5transfersCalled.Inc() results, resultsErr = s.getNEP5Transfers(reqParams) case "getvalidators": - getvalidatorsCalled.Inc() results, resultsErr = s.getValidators() case "getversion": - getversionCalled.Inc() results = result.Version{ Port: s.coreServer.Port, Nonce: s.coreServer.ID(), @@ -262,7 +251,6 @@ Methods: } case "getpeers": - getpeersCalled.Inc() peers := result.NewGetPeers() peers.AddUnconnected(s.coreServer.UnconnectedPeers()) peers.AddConnected(s.coreServer.ConnectedPeers()) @@ -270,7 +258,6 @@ Methods: results = peers case "getrawmempool": - getrawmempoolCalled.Inc() mp := s.chain.GetMemPool() hashList := make([]util.Uint256, 0) for _, item := range mp.GetVerifiedTransactions() { @@ -279,11 +266,9 @@ Methods: results = hashList case "getstorage": - getstorageCalled.Inc() results, resultsErr = s.getStorage(reqParams) case "validateaddress": - validateaddressCalled.Inc() param, ok := reqParams.Value(0) if !ok { resultsErr = response.ErrInvalidParams @@ -292,7 +277,6 @@ Methods: results = validateAddress(param.Value) case "getassetstate": - getassetstateCalled.Inc() param, ok := reqParams.ValueWithType(0, request.StringT) if !ok { resultsErr = response.ErrInvalidParams @@ -313,31 +297,24 @@ Methods: } case "getaccountstate": - getaccountstateCalled.Inc() results, resultsErr = s.getAccountState(reqParams, false) case "getcontractstate": - getcontractstateCalled.Inc() results, resultsErr = s.getContractState(reqParams) case "getrawtransaction": - getrawtransactionCalled.Inc() results, resultsErr = s.getrawtransaction(reqParams) case "gettransactionheight": - gettransactionheightCalled.Inc() results, resultsErr = s.getTransactionHeight(reqParams) case "gettxout": - gettxoutCalled.Inc() results, resultsErr = s.getTxOut(reqParams) case "getunclaimed": - getunclaimedCalled.Inc() results, resultsErr = s.getUnclaimed(reqParams) case "getunspents": - getunspentsCalled.Inc() results, resultsErr = s.getAccountState(reqParams, true) case "invoke": @@ -350,11 +327,9 @@ Methods: results, resultsErr = s.invokescript(reqParams) case "submitblock": - submitblockCalled.Inc() results, resultsErr = s.submitBlock(reqParams) case "sendrawtransaction": - sendrawtransactionCalled.Inc() results, resultsErr = s.sendrawtransaction(reqParams) default: From 70eb0b175ac015f5635aa640b407e91a96478e2d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:00:18 +0300 Subject: [PATCH 02/14] rpc: move getassetstate RPC to a separate func --- pkg/rpc/server/server.go | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index e14c8fb42..7f4bebb12 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -277,24 +277,7 @@ Methods: results = validateAddress(param.Value) case "getassetstate": - param, ok := reqParams.ValueWithType(0, request.StringT) - if !ok { - resultsErr = response.ErrInvalidParams - break Methods - } - - paramAssetID, err := param.GetUint256() - if err != nil { - resultsErr = response.ErrInvalidParams - break - } - - as := s.chain.GetAssetState(paramAssetID) - if as != nil { - results = result.NewAssetState(as) - } else { - resultsErr = response.NewRPCError("Unknown asset", "", nil) - } + results, resultsErr = s.getAssetState(reqParams) case "getaccountstate": results, resultsErr = s.getAccountState(reqParams, false) @@ -344,6 +327,24 @@ Methods: s.WriteResponse(req, w, results) } +func (s *Server) getAssetState(reqParams request.Params) (interface{}, error) { + param, ok := reqParams.ValueWithType(0, request.StringT) + if !ok { + return nil, response.ErrInvalidParams + } + + paramAssetID, err := param.GetUint256() + if err != nil { + return nil, response.ErrInvalidParams + } + + as := s.chain.GetAssetState(paramAssetID) + if as != nil { + return result.NewAssetState(as), nil + } + return nil, response.NewRPCError("Unknown asset", "", nil) +} + // getApplicationLog returns the contract log based on the specified txid. func (s *Server) getApplicationLog(reqParams request.Params) (interface{}, error) { param, ok := reqParams.Value(0) From 4e25c9121b1a0bd6391a5641cf1d651240634852 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:01:49 +0300 Subject: [PATCH 03/14] rpc: move validateaddress RPC to a separate func --- pkg/rpc/server/server.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 7f4bebb12..3333d5570 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -269,12 +269,7 @@ Methods: results, resultsErr = s.getStorage(reqParams) case "validateaddress": - param, ok := reqParams.Value(0) - if !ok { - resultsErr = response.ErrInvalidParams - break Methods - } - results = validateAddress(param.Value) + results, resultsErr = s.validateAddress(reqParams) case "getassetstate": results, resultsErr = s.getAssetState(reqParams) @@ -327,6 +322,14 @@ Methods: s.WriteResponse(req, w, results) } +func (s *Server) validateAddress(reqParams request.Params) (interface{}, error) { + param, ok := reqParams.Value(0) + if !ok { + return nil, response.ErrInvalidParams + } + return validateAddress(param.Value), nil +} + func (s *Server) getAssetState(reqParams request.Params) (interface{}, error) { param, ok := reqParams.ValueWithType(0, request.StringT) if !ok { From dfb4171e3ccccedad21c22088b5f9998cdbb86e8 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:03:01 +0300 Subject: [PATCH 04/14] rpc: move getrawmempool RPC to a separate func --- pkg/rpc/server/server.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 3333d5570..27e8ee4e8 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -258,12 +258,7 @@ Methods: results = peers case "getrawmempool": - mp := s.chain.GetMemPool() - hashList := make([]util.Uint256, 0) - for _, item := range mp.GetVerifiedTransactions() { - hashList = append(hashList, item.Tx.Hash()) - } - results = hashList + results, resultsErr = s.getRawMempool(reqParams) case "getstorage": results, resultsErr = s.getStorage(reqParams) @@ -322,6 +317,15 @@ Methods: s.WriteResponse(req, w, results) } +func (s *Server) getRawMempool(_ request.Params) (interface{}, error) { + mp := s.chain.GetMemPool() + hashList := make([]util.Uint256, 0) + for _, item := range mp.GetVerifiedTransactions() { + hashList = append(hashList, item.Tx.Hash()) + } + return hashList, nil +} + func (s *Server) validateAddress(reqParams request.Params) (interface{}, error) { param, ok := reqParams.Value(0) if !ok { From 99d02d5de0946020c6332238b86319905b5a91a4 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:03:58 +0300 Subject: [PATCH 05/14] rpc: move getpeers RPC to a separate func --- pkg/rpc/server/server.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 27e8ee4e8..84e2e3620 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -251,11 +251,7 @@ Methods: } case "getpeers": - peers := result.NewGetPeers() - peers.AddUnconnected(s.coreServer.UnconnectedPeers()) - peers.AddConnected(s.coreServer.ConnectedPeers()) - peers.AddBad(s.coreServer.BadPeers()) - results = peers + results, resultsErr = s.getPeers(reqParams) case "getrawmempool": results, resultsErr = s.getRawMempool(reqParams) @@ -317,6 +313,14 @@ Methods: s.WriteResponse(req, w, results) } +func (s *Server) getPeers(_ request.Params) (interface{}, error) { + peers := result.NewGetPeers() + peers.AddUnconnected(s.coreServer.UnconnectedPeers()) + peers.AddConnected(s.coreServer.ConnectedPeers()) + peers.AddBad(s.coreServer.BadPeers()) + return peers, nil +} + func (s *Server) getRawMempool(_ request.Params) (interface{}, error) { mp := s.chain.GetMemPool() hashList := make([]util.Uint256, 0) From 90fdde401882b03dca637cdfab8e6ea026994f7d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:04:57 +0300 Subject: [PATCH 06/14] rpc: move getversion RPC to a separate func --- pkg/rpc/server/server.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 84e2e3620..2f7956752 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -244,11 +244,7 @@ Methods: results, resultsErr = s.getValidators() case "getversion": - results = result.Version{ - Port: s.coreServer.Port, - Nonce: s.coreServer.ID(), - UserAgent: s.coreServer.UserAgent, - } + results, resultsErr = s.getVersion(reqParams) case "getpeers": results, resultsErr = s.getPeers(reqParams) @@ -313,6 +309,14 @@ Methods: s.WriteResponse(req, w, results) } +func (s *Server) getVersion(_ request.Params) (interface{}, error) { + return result.Version{ + Port: s.coreServer.Port, + Nonce: s.coreServer.ID(), + UserAgent: s.coreServer.UserAgent, + }, nil +} + func (s *Server) getPeers(_ request.Params) (interface{}, error) { peers := result.NewGetPeers() peers.AddUnconnected(s.coreServer.UnconnectedPeers()) From e442ebdb69b8d781dc65e7046765b4b13a164227 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:06:52 +0300 Subject: [PATCH 07/14] rpc: move getblockhash RPC to a separate func --- pkg/rpc/server/server.go | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 2f7956752..8ef4f1d10 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -210,18 +210,7 @@ Methods: results = s.chain.BlockHeight() + 1 case "getblockhash": - param, ok := reqParams.ValueWithType(0, request.NumberT) - if !ok { - resultsErr = response.ErrInvalidParams - break Methods - } - num, err := s.blockHeightFromParam(param) - if err != nil { - resultsErr = response.ErrInvalidParams - break Methods - } - - results = s.chain.GetHeaderHash(num) + results, resultsErr = s.getBlockHash(reqParams) case "getblockheader": results, resultsErr = s.getBlockHeader(reqParams) @@ -309,6 +298,19 @@ Methods: s.WriteResponse(req, w, results) } +func (s *Server) getBlockHash(reqParams request.Params) (interface{}, error) { + param, ok := reqParams.ValueWithType(0, request.NumberT) + if !ok { + return nil, response.ErrInvalidParams + } + num, err := s.blockHeightFromParam(param) + if err != nil { + return nil, response.ErrInvalidParams + } + + return s.chain.GetHeaderHash(num), nil +} + func (s *Server) getVersion(_ request.Params) (interface{}, error) { return result.Version{ Port: s.coreServer.Port, From 2ec5b9f08ada955c248571dcb8aac3cf32d9a74d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:08:30 +0300 Subject: [PATCH 08/14] rpc: move getblock RPC to a separate func --- pkg/rpc/server/server.go | 81 +++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 8ef4f1d10..9b08c3dc5 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -155,7 +155,6 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *request.In, reqParams incCounter(req.Method) -Methods: switch req.Method { case "getapplicationlog": results, resultsErr = s.getApplicationLog(reqParams) @@ -164,47 +163,7 @@ Methods: results = "0x" + s.chain.CurrentBlockHash().StringLE() case "getblock": - var hash util.Uint256 - - param, ok := reqParams.Value(0) - if !ok { - resultsErr = response.ErrInvalidParams - break Methods - } - - switch param.Type { - case request.StringT: - var err error - hash, err = param.GetUint256() - if err != nil { - resultsErr = response.ErrInvalidParams - break Methods - } - case request.NumberT: - num, err := s.blockHeightFromParam(param) - if err != nil { - resultsErr = response.ErrInvalidParams - break Methods - } - hash = s.chain.GetHeaderHash(num) - default: - resultsErr = response.ErrInvalidParams - break Methods - } - - block, err := s.chain.GetBlock(hash) - if err != nil { - resultsErr = response.NewInternalServerError(fmt.Sprintf("Problem locating block with hash: %s", hash), err) - break - } - - if len(reqParams) == 2 && reqParams[1].Value == 1 { - results = result.NewBlock(block, s.chain) - } else { - writer := io.NewBufBinWriter() - block.EncodeBinary(writer.BinWriter) - results = hex.EncodeToString(writer.Bytes()) - } + results, resultsErr = s.getBlock(reqParams) case "getblockcount": results = s.chain.BlockHeight() + 1 @@ -298,6 +257,44 @@ Methods: s.WriteResponse(req, w, results) } +func (s *Server) getBlock(reqParams request.Params) (interface{}, error) { + var hash util.Uint256 + + param, ok := reqParams.Value(0) + if !ok { + return nil, response.ErrInvalidParams + } + + switch param.Type { + case request.StringT: + var err error + hash, err = param.GetUint256() + if err != nil { + return nil, response.ErrInvalidParams + } + case request.NumberT: + num, err := s.blockHeightFromParam(param) + if err != nil { + return nil, response.ErrInvalidParams + } + hash = s.chain.GetHeaderHash(num) + default: + return nil, response.ErrInvalidParams + } + + block, err := s.chain.GetBlock(hash) + if err != nil { + return nil, response.NewInternalServerError(fmt.Sprintf("Problem locating block with hash: %s", hash), err) + } + + if len(reqParams) == 2 && reqParams[1].Value == 1 { + return result.NewBlock(block, s.chain), nil + } + writer := io.NewBufBinWriter() + block.EncodeBinary(writer.BinWriter) + return hex.EncodeToString(writer.Bytes()), nil +} + func (s *Server) getBlockHash(reqParams request.Params) (interface{}, error) { param, ok := reqParams.ValueWithType(0, request.NumberT) if !ok { From 969ed6e6e1f75e832c9e07152f15917ec48c0f6a Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:14:06 +0300 Subject: [PATCH 09/14] rpc: move getaccountstate/getunspents RPCs to a separate func --- pkg/rpc/server/server.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 9b08c3dc5..70ef1fa62 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -210,7 +210,7 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *request.In, reqParams results, resultsErr = s.getAssetState(reqParams) case "getaccountstate": - results, resultsErr = s.getAccountState(reqParams, false) + results, resultsErr = s.getAccountState(reqParams) case "getcontractstate": results, resultsErr = s.getContractState(reqParams) @@ -228,7 +228,7 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *request.In, reqParams results, resultsErr = s.getUnclaimed(reqParams) case "getunspents": - results, resultsErr = s.getAccountState(reqParams, true) + results, resultsErr = s.getUnspents(reqParams) case "invoke": results, resultsErr = s.invoke(reqParams) @@ -720,8 +720,16 @@ func (s *Server) getContractState(reqParams request.Params) (interface{}, error) return results, nil } +func (s *Server) getAccountState(ps request.Params) (interface{}, error) { + return s.getAccountStateAux(ps, false) +} + +func (s *Server) getUnspents(ps request.Params) (interface{}, error) { + return s.getAccountStateAux(ps, true) +} + // getAccountState returns account state either in short or full (unspents included) form. -func (s *Server) getAccountState(reqParams request.Params, unspents bool) (interface{}, error) { +func (s *Server) getAccountStateAux(reqParams request.Params, unspents bool) (interface{}, error) { var resultsErr error var results interface{} From 6e801d33f0bd6fdbd621cad4f24ab0c6bbf7153b Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:14:48 +0300 Subject: [PATCH 10/14] rpc: make a separate handler for every RPC Move getbestblockhash, getblockcount, getconnectioncount RPC. --- pkg/rpc/server/server.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 70ef1fa62..862d08e70 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -160,13 +160,13 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *request.In, reqParams results, resultsErr = s.getApplicationLog(reqParams) case "getbestblockhash": - results = "0x" + s.chain.CurrentBlockHash().StringLE() + results, resultsErr = s.getBestBlockHash(reqParams) case "getblock": results, resultsErr = s.getBlock(reqParams) case "getblockcount": - results = s.chain.BlockHeight() + 1 + results, resultsErr = s.getBlockCount(reqParams) case "getblockhash": results, resultsErr = s.getBlockHash(reqParams) @@ -181,7 +181,7 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *request.In, reqParams results, resultsErr = s.getClaimable(reqParams) case "getconnectioncount": - results = s.coreServer.PeerCount() + results, resultsErr = s.getConnectionCount(reqParams) case "getnep5balances": results, resultsErr = s.getNEP5Balances(reqParams) @@ -257,6 +257,18 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *request.In, reqParams s.WriteResponse(req, w, results) } +func (s *Server) getBestBlockHash(_ request.Params) (interface{}, error) { + return "0x" + s.chain.CurrentBlockHash().StringLE(), nil +} + +func (s *Server) getBlockCount(_ request.Params) (interface{}, error) { + return s.chain.BlockHeight() + 1, nil +} + +func (s *Server) getConnectionCount(_ request.Params) (interface{}, error) { + return s.coreServer.PeerCount(), nil +} + func (s *Server) getBlock(reqParams request.Params) (interface{}, error) { var hash util.Uint256 From 8236217a01b63958dc85d9ff6de71f5406ee4b4d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:26:29 +0300 Subject: [PATCH 11/14] rpc: make all handler have the same signature --- pkg/rpc/server/server.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 862d08e70..4d56dd698 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -189,7 +189,7 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *request.In, reqParams case "getnep5transfers": results, resultsErr = s.getNEP5Transfers(reqParams) case "getvalidators": - results, resultsErr = s.getValidators() + results, resultsErr = s.getValidators(reqParams) case "getversion": results, resultsErr = s.getVersion(reqParams) @@ -769,7 +769,7 @@ func (s *Server) getAccountStateAux(reqParams request.Params, unspents bool) (in } // getBlockSysFee returns the system fees of the block, based on the specified index. -func (s *Server) getBlockSysFee(reqParams request.Params) (util.Fixed8, error) { +func (s *Server) getBlockSysFee(reqParams request.Params) (interface{}, error) { param, ok := reqParams.ValueWithType(0, request.NumberT) if !ok { return 0, response.ErrInvalidParams @@ -853,7 +853,7 @@ func (s *Server) getUnclaimed(ps request.Params) (interface{}, error) { } // getValidators returns the current NEO consensus nodes information and voting status. -func (s *Server) getValidators() (interface{}, error) { +func (s *Server) getValidators(_ request.Params) (interface{}, error) { var validators keys.PublicKeys validators, err := s.chain.GetValidators() From 2ed417388b4ff936f6df4f1445cdb6a7596113a6 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 13 Mar 2020 10:29:49 +0300 Subject: [PATCH 12/14] rpc: unify RPC handlers Move all of them to a map. This can make it easier to add/remove RPC based on plugins and makes code less verbose. --- pkg/rpc/server/server.go | 128 +++++++++++---------------------------- 1 file changed, 37 insertions(+), 91 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 4d56dd698..f6c0dc58b 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -42,6 +42,39 @@ type ( } ) +var rpcHandlers = map[string]func(*Server, request.Params) (interface{}, error){ + "getaccountstate": (*Server).getAccountState, + "getapplicationlog": (*Server).getApplicationLog, + "getassetstate": (*Server).getAssetState, + "getbestblockhash": (*Server).getBestBlockHash, + "getblock": (*Server).getBlock, + "getblockcount": (*Server).getBlockCount, + "getblockhash": (*Server).getBlockHash, + "getblockheader": (*Server).getBlockHeader, + "getblocksysfee": (*Server).getBlockSysFee, + "getclaimable": (*Server).getClaimable, + "getconnectioncount": (*Server).getConnectionCount, + "getcontractstate": (*Server).getContractState, + "getnep5balances": (*Server).getNEP5Balances, + "getnep5transfers": (*Server).getNEP5Transfers, + "getpeers": (*Server).getPeers, + "getrawmempool": (*Server).getRawMempool, + "getrawtransaction": (*Server).getrawtransaction, + "getstorage": (*Server).getStorage, + "gettransactionheight": (*Server).getTransactionHeight, + "gettxout": (*Server).getTxOut, + "getunclaimed": (*Server).getUnclaimed, + "getunspents": (*Server).getUnspents, + "getvalidators": (*Server).getValidators, + "getversion": (*Server).getVersion, + "invoke": (*Server).invoke, + "invokefunction": (*Server).invokeFunction, + "invokescript": (*Server).invokescript, + "sendrawtransaction": (*Server).sendrawtransaction, + "submitblock": (*Server).submitBlock, + "validateaddress": (*Server).validateAddress, +} + var invalidBlockHeightError = func(index int, height int) error { return errors.Errorf("Param at index %d should be greater than or equal to 0 and less then or equal to current block height, got: %d", index, height) } @@ -155,97 +188,10 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *request.In, reqParams incCounter(req.Method) - switch req.Method { - case "getapplicationlog": - results, resultsErr = s.getApplicationLog(reqParams) - - case "getbestblockhash": - results, resultsErr = s.getBestBlockHash(reqParams) - - case "getblock": - results, resultsErr = s.getBlock(reqParams) - - case "getblockcount": - results, resultsErr = s.getBlockCount(reqParams) - - case "getblockhash": - results, resultsErr = s.getBlockHash(reqParams) - - case "getblockheader": - results, resultsErr = s.getBlockHeader(reqParams) - - case "getblocksysfee": - results, resultsErr = s.getBlockSysFee(reqParams) - - case "getclaimable": - results, resultsErr = s.getClaimable(reqParams) - - case "getconnectioncount": - results, resultsErr = s.getConnectionCount(reqParams) - - case "getnep5balances": - results, resultsErr = s.getNEP5Balances(reqParams) - - case "getnep5transfers": - results, resultsErr = s.getNEP5Transfers(reqParams) - case "getvalidators": - results, resultsErr = s.getValidators(reqParams) - - case "getversion": - results, resultsErr = s.getVersion(reqParams) - - case "getpeers": - results, resultsErr = s.getPeers(reqParams) - - case "getrawmempool": - results, resultsErr = s.getRawMempool(reqParams) - - case "getstorage": - results, resultsErr = s.getStorage(reqParams) - - case "validateaddress": - results, resultsErr = s.validateAddress(reqParams) - - case "getassetstate": - results, resultsErr = s.getAssetState(reqParams) - - case "getaccountstate": - results, resultsErr = s.getAccountState(reqParams) - - case "getcontractstate": - results, resultsErr = s.getContractState(reqParams) - - case "getrawtransaction": - results, resultsErr = s.getrawtransaction(reqParams) - - case "gettransactionheight": - results, resultsErr = s.getTransactionHeight(reqParams) - - case "gettxout": - results, resultsErr = s.getTxOut(reqParams) - - case "getunclaimed": - results, resultsErr = s.getUnclaimed(reqParams) - - case "getunspents": - results, resultsErr = s.getUnspents(reqParams) - - case "invoke": - results, resultsErr = s.invoke(reqParams) - - case "invokefunction": - results, resultsErr = s.invokeFunction(reqParams) - - case "invokescript": - results, resultsErr = s.invokescript(reqParams) - - case "submitblock": - results, resultsErr = s.submitBlock(reqParams) - - case "sendrawtransaction": - results, resultsErr = s.sendrawtransaction(reqParams) - - default: + handler, ok := rpcHandlers[req.Method] + if ok { + results, resultsErr = handler(s, reqParams) + } else { resultsErr = response.NewMethodNotFoundError(fmt.Sprintf("Method '%s' not supported", req.Method), nil) } From 57f37bc7a0e3c515d43b97be6c537836f69be0c0 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 25 Mar 2020 13:03:47 +0300 Subject: [PATCH 13/14] rpc: add metrics for invoke* RPCs --- pkg/rpc/server/prometheus.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/rpc/server/prometheus.go b/pkg/rpc/server/prometheus.go index 1a494dd70..caee0abab 100644 --- a/pkg/rpc/server/prometheus.go +++ b/pkg/rpc/server/prometheus.go @@ -33,6 +33,9 @@ var ( "getunspents", "getvalidators", "getversion", + "invoke", + "invokefunction", + "invokescript", "sendrawtransaction", "submitblock", "validateaddress", From 43495a49f459632056701775d0773a9a8c5eb86b Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 25 Mar 2020 15:19:12 +0300 Subject: [PATCH 14/14] rpc: reuse handlers map for prometheus metrics --- pkg/rpc/server/prometheus.go | 45 ++++-------------------------------- 1 file changed, 5 insertions(+), 40 deletions(-) diff --git a/pkg/rpc/server/prometheus.go b/pkg/rpc/server/prometheus.go index caee0abab..ccc4d4cc6 100644 --- a/pkg/rpc/server/prometheus.go +++ b/pkg/rpc/server/prometheus.go @@ -7,42 +7,7 @@ import ( ) // Metrics used in monitoring service. -var ( - rpcCalls = []string{ - "getaccountstate", - "getapplicationlog", - "getassetstate", - "getbestblock", - "getbestblockhash", - "getblockcount", - "getblockhash", - "getblockheader", - "getblocksysfee", - "getclaimable", - "getconnectioncount", - "getcontractstate", - "getnep5balances", - "getnep5transfers", - "getpeers", - "getrawmempool", - "getrawtransaction", - "getstorage", - "gettransactionheight", - "gettxout", - "getunclaimed", - "getunspents", - "getvalidators", - "getversion", - "invoke", - "invokefunction", - "invokescript", - "sendrawtransaction", - "submitblock", - "validateaddress", - } - - rpcCounter = map[string]prometheus.Counter{} -) +var rpcCounter = map[string]prometheus.Counter{} func incCounter(name string) { ctr, ok := rpcCounter[name] @@ -52,15 +17,15 @@ func incCounter(name string) { } func init() { - for i := range rpcCalls { + for call := range rpcHandlers { ctr := prometheus.NewCounter( prometheus.CounterOpts{ - Help: fmt.Sprintf("Number of calls to %s rpc endpoint", rpcCalls[i]), - Name: fmt.Sprintf("%s_called", rpcCalls[i]), + Help: fmt.Sprintf("Number of calls to %s rpc endpoint", call), + Name: fmt.Sprintf("%s_called", call), Namespace: "neogo", }, ) prometheus.MustRegister(ctr) - rpcCounter[rpcCalls[i]] = ctr + rpcCounter[call] = ctr } }