diff --git a/rpc/lib/rpc_test.go b/rpc/lib/rpc_test.go index cd42f20a6..2f61f3887 100644 --- a/rpc/lib/rpc_test.go +++ b/rpc/lib/rpc_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - data "github.com/tendermint/go-data" + "github.com/tendermint/go-wire/data" client "github.com/tendermint/tendermint/rpc/lib/client" server "github.com/tendermint/tendermint/rpc/lib/server" types "github.com/tendermint/tendermint/rpc/lib/types" @@ -64,19 +64,31 @@ type ResultEcho struct { Value string } +type ResultEchoInt struct { + Value int +} + type ResultEchoBytes struct { Value []byte } +type ResultEchoDataBytes struct { + Value data.Bytes +} + var resultMapper = data.NewMapper(Result{}). RegisterImplementation(&ResultEcho{}, "echo", 0x1). - RegisterImplementation(&ResultEchoBytes{}, "echo_bytes", 0x2) + RegisterImplementation(&ResultEchoBytes{}, "echo_bytes", 0x2). + RegisterImplementation(&ResultEchoDataBytes{}, "echo_data_bytes", 0x3). + RegisterImplementation(&ResultEchoInt{}, "echo_int", 0x4) // Define some routes var Routes = map[string]*server.RPCFunc{ - "echo": server.NewRPCFunc(EchoResult, "arg"), - "echo_ws": server.NewWSRPCFunc(EchoWSResult, "arg"), - "echo_bytes": server.NewRPCFunc(EchoBytesResult, "arg"), + "echo": server.NewRPCFunc(EchoResult, "arg"), + "echo_ws": server.NewWSRPCFunc(EchoWSResult, "arg"), + "echo_bytes": server.NewRPCFunc(EchoBytesResult, "arg"), + "echo_data_bytes": server.NewRPCFunc(EchoDataBytesResult, "arg"), + "echo_int": server.NewRPCFunc(EchoIntResult, "arg"), } func EchoResult(v string) (Result, error) { @@ -87,10 +99,18 @@ func EchoWSResult(wsCtx types.WSRPCContext, v string) (Result, error) { return Result{&ResultEcho{v}}, nil } +func EchoIntResult(v int) (Result, error) { + return Result{&ResultEchoInt{v}}, nil +} + func EchoBytesResult(v []byte) (Result, error) { return Result{&ResultEchoBytes{v}}, nil } +func EchoDataBytesResult(v data.Bytes) (Result, error) { + return Result{&ResultEchoDataBytes{v}}, nil +} + // launch unix and tcp servers func init() { cmd := exec.Command("rm", "-f", unixSocket) @@ -139,6 +159,17 @@ func echoViaHTTP(cl client.HTTPClient, val string) (string, error) { return result.Unwrap().(*ResultEcho).Value, nil } +func echoIntViaHTTP(cl client.HTTPClient, val int) (int, error) { + params := map[string]interface{}{ + "arg": val, + } + var result Result + if _, err := cl.Call("echo_int", params, &result); err != nil { + return 0, err + } + return result.Unwrap().(*ResultEchoInt).Value, nil +} + func echoBytesViaHTTP(cl client.HTTPClient, bytes []byte) ([]byte, error) { params := map[string]interface{}{ "arg": bytes, @@ -150,6 +181,17 @@ func echoBytesViaHTTP(cl client.HTTPClient, bytes []byte) ([]byte, error) { return result.Unwrap().(*ResultEchoBytes).Value, nil } +func echoDataBytesViaHTTP(cl client.HTTPClient, bytes data.Bytes) (data.Bytes, error) { + params := map[string]interface{}{ + "arg": bytes, + } + var result Result + if _, err := cl.Call("echo_data_bytes", params, &result); err != nil { + return []byte{}, err + } + return result.Unwrap().(*ResultEchoDataBytes).Value, nil +} + func testWithHTTPClient(t *testing.T, cl client.HTTPClient) { val := "acbd" got, err := echoViaHTTP(cl, val) @@ -160,6 +202,18 @@ func testWithHTTPClient(t *testing.T, cl client.HTTPClient) { got2, err := echoBytesViaHTTP(cl, val2) require.Nil(t, err) assert.Equal(t, got2, val2) + + val3 := data.Bytes(randBytes(t)) + got3, err := echoDataBytesViaHTTP(cl, val3) + require.Nil(t, err) + assert.Equal(t, got3, val3) + + /* + val4 := rand.Intn(10000) + got4, err := echoIntViaHTTP(cl, val4) + require.Nil(t, err) + assert.Equal(t, got4, val4) + */ } func echoViaWS(cl *client.WSClient, val string) (string, error) { diff --git a/rpc/lib/server/handlers.go b/rpc/lib/server/handlers.go index 27451c23d..1c25d9e75 100644 --- a/rpc/lib/server/handlers.go +++ b/rpc/lib/server/handlers.go @@ -2,6 +2,7 @@ package rpcserver import ( "bytes" + "encoding/base64" "encoding/hex" "encoding/json" "fmt" @@ -14,7 +15,8 @@ import ( "github.com/gorilla/websocket" "github.com/pkg/errors" - wire "github.com/tendermint/go-wire" + //wire "github.com/tendermint/go-wire" + "github.com/tendermint/go-wire/data" types "github.com/tendermint/tendermint/rpc/lib/types" cmn "github.com/tendermint/tmlibs/common" events "github.com/tendermint/tmlibs/events" @@ -204,7 +206,32 @@ func jsonParamsToArgsWS(rpcFunc *RPCFunc, paramsI interface{}, wsCtx types.WSRPC func _jsonObjectToArg(ty reflect.Type, object interface{}) (reflect.Value, error) { var err error v := reflect.New(ty) - wire.ReadJSONObjectPtr(v.Interface(), object, &err) + + // if the object is a byte array, we need to decode it + if ty.Kind() == reflect.Slice && ty.Elem().Kind() == reflect.Uint8 { + s, ok := object.(string) + if !ok { + return v, fmt.Errorf("cmah") + } + + // if its data.Bytes, use hex + // else use base64 + dbty := reflect.TypeOf(data.Bytes{}) + if ty == dbty { + decoded, err := hex.DecodeString(s) + if err != nil { + return v, err + } + object = decoded + } else { + decoded, err := base64.StdEncoding.DecodeString(s) + if err != nil { + return v, err + } + object = decoded + } + } + v.Elem().Set(reflect.ValueOf(object)) if err != nil { return v, err }