rpc: decode args without wire
This commit is contained in:
parent
6c60c07f16
commit
acfbea6d49
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"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"
|
client "github.com/tendermint/tendermint/rpc/lib/client"
|
||||||
server "github.com/tendermint/tendermint/rpc/lib/server"
|
server "github.com/tendermint/tendermint/rpc/lib/server"
|
||||||
types "github.com/tendermint/tendermint/rpc/lib/types"
|
types "github.com/tendermint/tendermint/rpc/lib/types"
|
||||||
|
@ -64,19 +64,31 @@ type ResultEcho struct {
|
||||||
Value string
|
Value string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResultEchoInt struct {
|
||||||
|
Value int
|
||||||
|
}
|
||||||
|
|
||||||
type ResultEchoBytes struct {
|
type ResultEchoBytes struct {
|
||||||
Value []byte
|
Value []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResultEchoDataBytes struct {
|
||||||
|
Value data.Bytes
|
||||||
|
}
|
||||||
|
|
||||||
var resultMapper = data.NewMapper(Result{}).
|
var resultMapper = data.NewMapper(Result{}).
|
||||||
RegisterImplementation(&ResultEcho{}, "echo", 0x1).
|
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
|
// Define some routes
|
||||||
var Routes = map[string]*server.RPCFunc{
|
var Routes = map[string]*server.RPCFunc{
|
||||||
"echo": server.NewRPCFunc(EchoResult, "arg"),
|
"echo": server.NewRPCFunc(EchoResult, "arg"),
|
||||||
"echo_ws": server.NewWSRPCFunc(EchoWSResult, "arg"),
|
"echo_ws": server.NewWSRPCFunc(EchoWSResult, "arg"),
|
||||||
"echo_bytes": server.NewRPCFunc(EchoBytesResult, "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) {
|
func EchoResult(v string) (Result, error) {
|
||||||
|
@ -87,10 +99,18 @@ func EchoWSResult(wsCtx types.WSRPCContext, v string) (Result, error) {
|
||||||
return Result{&ResultEcho{v}}, nil
|
return Result{&ResultEcho{v}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EchoIntResult(v int) (Result, error) {
|
||||||
|
return Result{&ResultEchoInt{v}}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func EchoBytesResult(v []byte) (Result, error) {
|
func EchoBytesResult(v []byte) (Result, error) {
|
||||||
return Result{&ResultEchoBytes{v}}, nil
|
return Result{&ResultEchoBytes{v}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EchoDataBytesResult(v data.Bytes) (Result, error) {
|
||||||
|
return Result{&ResultEchoDataBytes{v}}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// launch unix and tcp servers
|
// launch unix and tcp servers
|
||||||
func init() {
|
func init() {
|
||||||
cmd := exec.Command("rm", "-f", unixSocket)
|
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
|
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) {
|
func echoBytesViaHTTP(cl client.HTTPClient, bytes []byte) ([]byte, error) {
|
||||||
params := map[string]interface{}{
|
params := map[string]interface{}{
|
||||||
"arg": bytes,
|
"arg": bytes,
|
||||||
|
@ -150,6 +181,17 @@ func echoBytesViaHTTP(cl client.HTTPClient, bytes []byte) ([]byte, error) {
|
||||||
return result.Unwrap().(*ResultEchoBytes).Value, nil
|
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) {
|
func testWithHTTPClient(t *testing.T, cl client.HTTPClient) {
|
||||||
val := "acbd"
|
val := "acbd"
|
||||||
got, err := echoViaHTTP(cl, val)
|
got, err := echoViaHTTP(cl, val)
|
||||||
|
@ -160,6 +202,18 @@ func testWithHTTPClient(t *testing.T, cl client.HTTPClient) {
|
||||||
got2, err := echoBytesViaHTTP(cl, val2)
|
got2, err := echoBytesViaHTTP(cl, val2)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, got2, val2)
|
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) {
|
func echoViaWS(cl *client.WSClient, val string) (string, error) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package rpcserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -14,7 +15,8 @@ import (
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/pkg/errors"
|
"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"
|
types "github.com/tendermint/tendermint/rpc/lib/types"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
events "github.com/tendermint/tmlibs/events"
|
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) {
|
func _jsonObjectToArg(ty reflect.Type, object interface{}) (reflect.Value, error) {
|
||||||
var err error
|
var err error
|
||||||
v := reflect.New(ty)
|
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 {
|
if err != nil {
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue