Skip to content

Commit

Permalink
Move jsonrpc changes of proxy to cache package
Browse files Browse the repository at this point in the history
  • Loading branch information
dkeysil committed Mar 11, 2024
1 parent 773701f commit c28a758
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 63 deletions.
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type JsonRpcProxyConfig struct {
}

type JsonRpcCacheConfig struct {
DispatcherURL string `yaml:"dispatcherUrl" json:"dispatcherUrl" validate:"omitempty,url"`
DispatcherURL string `yaml:"dispatcherUrl" json:"dispatcherUrl" default:"https://dispatcher.forta.network/batch" validate:"omitempty,url"`
CacheExpirePeriodSeconds int `yaml:"cacheExpirePeriodSeconds" json:"cacheExpirePeriodSeconds" default:"300"`
}

Expand Down
13 changes: 6 additions & 7 deletions services/json-rpc/cache/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@ import (
"encoding/json"
"net/http"

jrp "github.com/forta-network/forta-node/services/json-rpc"
log "github.com/sirupsen/logrus"
)

func writeBadRequest(w http.ResponseWriter, req *jrp.JsonRpcReq, err error) {
func writeBadRequest(w http.ResponseWriter, req *jsonRpcReq, err error) {
if req == nil {
http.Error(w, "bad request", http.StatusBadRequest)
return
}

w.WriteHeader(http.StatusBadRequest)

if err := json.NewEncoder(w).Encode(&jrp.ErrorResponse{
if err := json.NewEncoder(w).Encode(&errorResponse{
JSONRPC: "2.0",
ID: req.ID,
Error: jrp.JsonRpcError{
Error: jsonRpcError{
Code: -32600,
Message: err.Error(),
},
Expand All @@ -28,13 +27,13 @@ func writeBadRequest(w http.ResponseWriter, req *jrp.JsonRpcReq, err error) {
}
}

func writeUnauthorized(w http.ResponseWriter, req *jrp.JsonRpcReq) {
func writeUnauthorized(w http.ResponseWriter, req *jsonRpcReq) {
w.WriteHeader(http.StatusUnauthorized)

if err := json.NewEncoder(w).Encode(&jrp.ErrorResponse{
if err := json.NewEncoder(w).Encode(&errorResponse{
JSONRPC: "2.0",
ID: req.ID,
Error: jrp.JsonRpcError{
Error: jsonRpcError{
Code: -32000,
Message: "unauthorized",
},
Expand Down
9 changes: 4 additions & 5 deletions services/json-rpc/cache/json_rpc_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/forta-network/forta-node/clients"
"github.com/forta-network/forta-node/clients/r2cbe"
"github.com/forta-network/forta-node/config"
jrp "github.com/forta-network/forta-node/services/json-rpc"
log "github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -78,7 +77,7 @@ func (p *JsonRpcCache) Name() string {

func (c *JsonRpcCache) Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
req, err := jrp.DecodeBody(r)
req, err := decodeBody(r)
if err != nil {
writeBadRequest(w, req, err)
return
Expand All @@ -98,10 +97,10 @@ func (c *JsonRpcCache) Handler() http.Handler {

result, ok := c.cache.Get(uint64(chainID), req.Method, string(req.Params))
if !ok {
resp := &jrp.JsonRpcResp{
resp := &jsonRpcResp{
ID: req.ID,
Result: nil,
Error: &jrp.JsonRpcError{
Error: &jsonRpcError{
Code: -32603,
Message: "result not found in cache",
},
Expand All @@ -119,7 +118,7 @@ func (c *JsonRpcCache) Handler() http.Handler {
return
}

resp := &jrp.JsonRpcResp{
resp := &jsonRpcResp{
ID: req.ID,
Result: json.RawMessage(b),
}
Expand Down
5 changes: 2 additions & 3 deletions services/json-rpc/cache/json_rpc_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

mock_clients "github.com/forta-network/forta-node/clients/mocks"
"github.com/forta-network/forta-node/config"
jrp "github.com/forta-network/forta-node/services/json-rpc"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -55,7 +54,7 @@ func TestJsonRpcCache(t *testing.T) {

<-appended

jrpReq := jrp.JsonRpcReq{
jrpReq := jsonRpcReq{
ID: json.RawMessage("1"),
Method: "eth_blockNumber",
Params: json.RawMessage("[]"),
Expand All @@ -73,7 +72,7 @@ func TestJsonRpcCache(t *testing.T) {
require.Equal(t, 200, rw.Code)

b = rw.Body.Bytes()
var resp jrp.JsonRpcResp
var resp jsonRpcResp
require.NoError(t, json.Unmarshal(b, &resp))
require.Nil(t, resp.Error)

Expand Down
38 changes: 38 additions & 0 deletions services/json-rpc/cache/jsonrpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package json_rpc_cache

import (
"encoding/json"
"fmt"
"net/http"
)

type jsonRpcReq struct {
ID json.RawMessage `json:"id"`
Method string `json:"method"`
Params json.RawMessage `json:"params"`
}

type jsonRpcResp struct {
ID json.RawMessage `json:"id"`
Result json.RawMessage `json:"result"`
Error *jsonRpcError `json:"error"`
}

type errorResponse struct {
JSONRPC string `json:"jsonrpc"`
ID json.RawMessage `json:"id"`
Error jsonRpcError `json:"error"`
}

type jsonRpcError struct {
Code int `json:"code"`
Message string `json:"message"`
}

func decodeBody(req *http.Request) (*jsonRpcReq, error) {
var decodedBody jsonRpcReq
if err := json.NewDecoder(req.Body).Decode(&decodedBody); err != nil {
return nil, fmt.Errorf("failed to decode json-rpc request body")
}
return &decodedBody, nil
}
39 changes: 7 additions & 32 deletions services/json-rpc/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,17 @@ import (
"net/http"
)

type JsonRpcReq struct {
ID json.RawMessage `json:"id"`
Method string `json:"method"`
Params json.RawMessage `json:"params"`
type jsonRpcReq struct {
Method string `json:"method"`
}

type JsonRpcResp struct {
ID json.RawMessage `json:"id"`
Result json.RawMessage `json:"result"`
Error *JsonRpcError `json:"error"`
}

func DecodeBody(req *http.Request) (*JsonRpcReq, error) {
var decodedBody JsonRpcReq
if err := json.NewDecoder(req.Body).Decode(&decodedBody); err != nil {
fmt.Println(err)
return nil, fmt.Errorf("failed to decode json-rpc request body")
}
return &decodedBody, nil
}

func decodeAndReplaceBody(req *http.Request) (*JsonRpcReq, error) {
b, err := io.ReadAll(req.Body)
if err != nil {
return nil, fmt.Errorf("failed to read request body")
}
func decodeAndReplaceBody(req *http.Request) (*jsonRpcReq, error) {
b, _ := io.ReadAll(req.Body)
req.Body.Close()
req.Body = io.NopCloser(bytes.NewBuffer(b))

decodedBody, err := DecodeBody(req)
if err != nil {
var decodedBody jsonRpcReq
if err := json.Unmarshal(b, &decodedBody); err != nil {
return nil, fmt.Errorf("failed to decode json-rpc request body")
}

req.Body.Close()

req.Body = io.NopCloser(bytes.NewBuffer(b))
return decodedBody, nil
return &decodedBody, nil
}
20 changes: 12 additions & 8 deletions services/json-rpc/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,34 @@ import (
log "github.com/sirupsen/logrus"
)

type ErrorResponse struct {
JSONRPC string `json:"jsonrpc"`
ID json.RawMessage `json:"id"`
Error JsonRpcError `json:"error"`
type requestPayload struct {
ID int `json:"id"`
}

type JsonRpcError struct {
type errorResponse struct {
JSONRPC string `json:"jsonrpc"`
ID int `json:"id"`
Error jsonRpcError `json:"error"`
}

type jsonRpcError struct {
Code int `json:"code"`
Message string `json:"message"`
}

func writeTooManyReqsErr(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusTooManyRequests)

var reqPayload JsonRpcReq
var reqPayload requestPayload
if err := json.NewDecoder(req.Body).Decode(&reqPayload); err != nil {
log.WithError(err).Error("failed to decode jsonrpc request body")
return
}

if err := json.NewEncoder(w).Encode(&ErrorResponse{
if err := json.NewEncoder(w).Encode(&errorResponse{
JSONRPC: "2.0",
ID: reqPayload.ID,
Error: JsonRpcError{
Error: jsonRpcError{
Code: -32000,
Message: "agent exceeds scan node request limit",
},
Expand Down
7 changes: 2 additions & 5 deletions services/json-rpc/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,10 @@ func TestTooManyReqsError(t *testing.T) {

resp := recorder.Result()
r.Equal(http.StatusTooManyRequests, resp.StatusCode)
var errResp ErrorResponse
var errResp errorResponse
r.NoError(json.NewDecoder(resp.Body).Decode(&errResp))
r.Equal("2.0", errResp.JSONRPC)
var id int
err = json.Unmarshal(errResp.ID, &id)
r.NoError(err)
r.Equal(testRequestID, id)
r.Equal(testRequestID, errResp.ID)
r.Equal(-32000, errResp.Error.Code)
r.Contains(errResp.Error.Message, "exceeds")
}
3 changes: 1 addition & 2 deletions services/supervisor/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,7 @@ func (sup *SupervisorService) start() error {
hostFortaDir: config.DefaultContainerFortaDirPath,
},
Ports: map[string]string{
"": config.DefaultHealthPort, // random host port
"8575": config.DefaultBotJSONRPCCachePort,
"": config.DefaultHealthPort, // random host port
},
DialHost: true,
NetworkID: nodeNetworkID,
Expand Down

0 comments on commit c28a758

Please sign in to comment.