From 92797c4ea51bce9fc7d2f50b8f6156f2d5204497 Mon Sep 17 00:00:00 2001 From: Mohammed Sohail Date: Tue, 14 Dec 2021 17:50:07 +0300 Subject: [PATCH] add: batch rpc calls --- internal/server/handlers.go | 63 ++++++++++++++++++------------------- internal/server/router.go | 28 +++++++++++++++++ pkg/rpc/client.go | 16 ++++++++-- 3 files changed, 73 insertions(+), 34 deletions(-) diff --git a/internal/server/handlers.go b/internal/server/handlers.go index 82a57a9..7193618 100644 --- a/internal/server/handlers.go +++ b/internal/server/handlers.go @@ -1,52 +1,51 @@ package server import ( - "net/http" - - "github.com/gin-gonic/gin" - "github.com/rs/zerolog/log" - "git.grassecon.org/grassrootseconomics/openethereum-node-status/pkg/rpc" -) - -type ( - R struct { - Result string `json:"result"` - } - - P map[string]interface{} + "github.com/rs/zerolog/log" + "github.com/ybbus/jsonrpc/v2" ) var ( RpcClient rpc.RpcClient ) -func metricsHandler(c *gin.Context) { - // pllholder rpc call - rpcResponse, err := RpcClient.EthRpcCall("eth_gasPrice") +type BatchResponse struct { + SyncComplete bool + ChainName string +} + +func batchCall() (bool, BatchResponse) { + var batchResponse BatchResponse + + rpcResponses, err := RpcClient.EthBatchRpcCall(jsonrpc.RPCRequests{ + jsonrpc.NewRequest("eth_syncing"), + jsonrpc.NewRequest("parity_chain"), + }) + if err != nil { log.Error(). Err(err). Str("module", "server"). - Msg("rpc call failed") + Msg("error in batch responses") + return false, batchResponse } - value, err := rpcResponse.GetString() - if err != nil { - log.Error(). - Err(err). - Str("module", "server"). - Msg("rpc response to string conversion failed") + if syncStatus, ok := rpcResponses[0]; ok { + val, err := syncStatus.GetBool() + if err != nil { + return false, batchResponse + } + batchResponse.SyncComplete = !val } - c.JSON(http.StatusOK, gin.H{ - "ok": true, - "data": value, - }) -} + if chainName, ok := rpcResponses[1]; ok { + val, err := chainName.GetString() + if err != nil { + return false, batchResponse + } + batchResponse.ChainName = val + } -func healthHandler(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{ - "ok": true, - }) + return true, batchResponse } diff --git a/internal/server/router.go b/internal/server/router.go index 82c9469..e547b49 100644 --- a/internal/server/router.go +++ b/internal/server/router.go @@ -1,6 +1,9 @@ package server import ( + "fmt" + "net/http" + "github.com/gin-gonic/gin" ) @@ -15,3 +18,28 @@ func Start(port string, ginMode string) error { return router.Run(port) } + +func healthHandler(c *gin.Context) { + allOk, data := batchCall() + + fmt.Println(data.SyncComplete) + if !allOk { + c.JSON(http.StatusExpectationFailed, gin.H{ + "ok": false, + "message": "could not get node health status", + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "ok": true, + "syncComplete": data.SyncComplete, + "chainName": data.ChainName, + }) +} + +func metricsHandler(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "ok": true, + }) +} diff --git a/pkg/rpc/client.go b/pkg/rpc/client.go index 1fc7712..29b113e 100644 --- a/pkg/rpc/client.go +++ b/pkg/rpc/client.go @@ -19,12 +19,24 @@ func NewRpcClient(endpoint string) RpcClient { func (r *RpcClient) EthRpcCall(method string) (*jsonrpc.RPCResponse, error) { response, err := r.ethClient.Call(method) if err != nil { - return response, err + return nil, err } if response.Error != nil { - return response, fmt.Errorf("rpc client error: (code %d) %s", response.Error.Code, response.Error.Message) + return nil, fmt.Errorf("rpc client error: (code %d) %s", response.Error.Code, response.Error.Message) } return response, nil } + +func (r *RpcClient) EthBatchRpcCall(batchedMethods jsonrpc.RPCRequests) (map[int]*jsonrpc.RPCResponse, error) { + response, _ := r.ethClient.CallBatch(batchedMethods) + + if response.HasError() { + return nil, fmt.Errorf("batch rpc request failed") + } + + results := response.AsMap() + + return results, nil +}