From 649a9c2d1ad91cc0ba14134a00668f905fe52973 Mon Sep 17 00:00:00 2001 From: Tuan Pham Anh Date: Thu, 6 Apr 2023 17:34:05 +0700 Subject: [PATCH] fix: jsonrpc to support both positional parameters and named parameters https://github.com/notional-labs/subnode/issues/15 --- config_test.go | 2 +- rpc_server.go | 60 +++++++++++++++++++++++++++++++++++----------- rpc_server_test.go | 26 ++++++++++++++++++++ state_test.go | 4 ++-- 4 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 rpc_server_test.go diff --git a/config_test.go b/config_test.go index 2b2c912..b9f1c9f 100644 --- a/config_test.go +++ b/config_test.go @@ -24,7 +24,7 @@ upstream: func TestGetBackendNodeType(t *testing.T) { b := Backend{ Rpc: "http://pruned", - Blocks: []int{10}, + Blocks: []int64{10}, } assert.Equal(t, GetBackendNodeType(&b), BackendNodeTypePruned) diff --git a/rpc_server.go b/rpc_server.go index 4047ba0..a0811e3 100644 --- a/rpc_server.go +++ b/rpc_server.go @@ -79,9 +79,13 @@ func StartRpcServer() { m0 := j0.(map[string]interface{}) method := m0["method"].(string) - params := m0["params"].([]interface{}) + //params := m0["params"].([]interface{}) - fmt.Printf("method=%s, params=%+v\n", method, params) + fmt.Printf("method=%s, params=%+v\n", method, m0["params"]) + + // note that params could be positional parameters or named parameters + // eg., "params": [ "9045128", "1", "30" ] + // or "params": { "height": "9045128", "page": "1", "per_page": "30" } if method == "abci_info" || strings.HasPrefix(method, "broadcast_") || @@ -105,14 +109,28 @@ func StartRpcServer() { method == "consensus_params" || method == "validators" { - // height is 1st param - if len(params) < 1 { - SendError(w) + height := int64(0) + + if positionalParams, ok := m0["params"].([]interface{}); ok { // positional parameters + // height is 1st param + if len(positionalParams) < 1 { + SendError(w) + } + + heightParam := positionalParams[0].(string) + height, err = strconv.ParseInt(heightParam, 10, 64) + if err != nil { + SendError(w) + } + } else if namedParams, ok := m0["params"].(map[string]interface{}); ok { // named parameters + heightParam := namedParams["height"].(string) + height, err = strconv.ParseInt(heightParam, 10, 64) + if err != nil { + SendError(w) + } } - heightParam := params[0].(string) - height, err := strconv.ParseInt(heightParam, 10, 64) - if err != nil { + if height == 0 { SendError(w) } @@ -123,14 +141,28 @@ func StartRpcServer() { selectedHost = node.Backend.Rpc } else if method == "abci_query" { - // height is 3rd param - if len(params) < 3 { - SendError(w) + height := int64(0) + + if positionalParams, ok := m0["params"].([]interface{}); ok { // positional parameters + // height is 3rd param + if len(positionalParams) < 3 { + SendError(w) + } + + heightParam := positionalParams[2].(string) + height, err = strconv.ParseInt(heightParam, 10, 64) + if err != nil { + SendError(w) + } + } else if namedParams, ok := m0["params"].(map[string]interface{}); ok { // named parameters + heightParam := namedParams["height"].(string) + height, err = strconv.ParseInt(heightParam, 10, 64) + if err != nil { + SendError(w) + } } - heightParam := params[2].(string) - height, err := strconv.ParseInt(heightParam, 10, 64) - if err != nil { + if height == 0 { SendError(w) } diff --git a/rpc_server_test.go b/rpc_server_test.go new file mode 100644 index 0000000..e3a512b --- /dev/null +++ b/rpc_server_test.go @@ -0,0 +1,26 @@ +package main + +import ( + "encoding/json" + "fmt" + "github.com/stretchr/testify/assert" + "reflect" + "testing" +) + +func TestJsonRpcParams(t *testing.T) { + jsonText := []byte(`{"jsonrpc": "2.0", "id": "0", "method": "validators", "params": { "height": "9045128", "page": "1", "per_page": "30" }}`) + //jsonText := []byte(`{"jsonrpc": "2.0", "id": "0", "method": "validators", "params": ["9045128", "1", "30"]}`) + + var j0 interface{} + err := json.Unmarshal(jsonText, &j0) + assert.NoError(t, err) + + m0 := j0.(map[string]interface{}) + //method := m0["method"].(string) + //params := m0["params"].([]interface{}) + // + //fmt.Printf("method=%s, params=%+v\n", method, params) + + fmt.Println(reflect.TypeOf(m0["params"])) +} diff --git a/state_test.go b/state_test.go index 0ffa408..fb657d6 100644 --- a/state_test.go +++ b/state_test.go @@ -8,11 +8,11 @@ import ( func TestSelectPrunedNode(t *testing.T) { pruned := Backend{ Rpc: "http://pruned", - Blocks: []int{10}, + Blocks: []int64{10}, } archive := Backend{ Rpc: "http://archive", - Blocks: []int{}, + Blocks: []int64{}, } cfg = &Config{