BROKEN: attempt to replace go-wire.JSON with json.Unmarshall in rpc

This commit is contained in:
Ethan Frey
2017-04-28 16:24:06 +02:00
parent bff8402fe8
commit 6c60c07f16
7 changed files with 77 additions and 52 deletions

View File

@ -1,10 +1,10 @@
package client package client
import ( import (
"encoding/json"
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
wire "github.com/tendermint/go-wire"
data "github.com/tendermint/go-wire/data" data "github.com/tendermint/go-wire/data"
ctypes "github.com/tendermint/tendermint/rpc/core/types" ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/rpc/lib/client" "github.com/tendermint/tendermint/rpc/lib/client"
@ -336,7 +336,7 @@ func (w *WSEvents) eventListener() {
// on the merry way to the EventSwitch // on the merry way to the EventSwitch
func (w *WSEvents) parseEvent(data []byte) (err error) { func (w *WSEvents) parseEvent(data []byte) (err error) {
result := new(ctypes.TMResult) result := new(ctypes.TMResult)
wire.ReadJSONPtr(result, data, &err) err = json.Unmarshal(data, result)
if err != nil { if err != nil {
return err return err
} }

View File

@ -12,7 +12,6 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
wire "github.com/tendermint/go-wire"
types "github.com/tendermint/tendermint/rpc/lib/types" types "github.com/tendermint/tendermint/rpc/lib/types"
) )
@ -70,15 +69,15 @@ func NewJSONRPCClient(remote string) *JSONRPCClient {
func (c *JSONRPCClient) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) { func (c *JSONRPCClient) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
// we need this step because we attempt to decode values using `go-wire` // we need this step because we attempt to decode values using `go-wire`
// (handlers.go:176) on the server side // (handlers.go:176) on the server side
encodedParams := make(map[string]interface{}) // encodedParams := make(map[string]interface{})
for k, v := range params { // for k, v := range params {
bytes := json.RawMessage(wire.JSONBytes(v)) // bytes := json.RawMessage(wire.JSONBytes(v))
encodedParams[k] = &bytes // encodedParams[k] = &bytes
} // }
request := types.RPCRequest{ request := types.RPCRequest{
JSONRPC: "2.0", JSONRPC: "2.0",
Method: method, Method: method,
Params: encodedParams, Params: params,
ID: "", ID: "",
} }
requestBytes, err := json.Marshal(request) requestBytes, err := json.Marshal(request)
@ -153,7 +152,7 @@ func unmarshalResponseBytes(responseBytes []byte, result interface{}) (interface
return nil, errors.Errorf("Response error: %v", errorStr) return nil, errors.Errorf("Response error: %v", errorStr)
} }
// unmarshal the RawMessage into the result // unmarshal the RawMessage into the result
result = wire.ReadJSONPtr(result, *response.Result, &err) err = json.Unmarshal(*response.Result, result)
if err != nil { if err != nil {
return nil, errors.Errorf("Error unmarshalling rpc response result: %v", err) return nil, errors.Errorf("Error unmarshalling rpc response result: %v", err)
} }
@ -176,8 +175,6 @@ func argsToURLValues(args map[string]interface{}) (url.Values, error) {
} }
func argsToJson(args map[string]interface{}) error { func argsToJson(args map[string]interface{}) error {
var n int
var err error
for k, v := range args { for k, v := range args {
rt := reflect.TypeOf(v) rt := reflect.TypeOf(v)
isByteSlice := rt.Kind() == reflect.Slice && rt.Elem().Kind() == reflect.Uint8 isByteSlice := rt.Kind() == reflect.Slice && rt.Elem().Kind() == reflect.Uint8
@ -188,12 +185,11 @@ func argsToJson(args map[string]interface{}) error {
} }
// Pass everything else to go-wire // Pass everything else to go-wire
buf := new(bytes.Buffer) data, err := json.Marshal(v)
wire.WriteJSON(v, buf, &n, &err)
if err != nil { if err != nil {
return err return err
} }
args[k] = buf.String() args[k] = string(data)
} }
return nil return nil
} }

View File

@ -8,9 +8,8 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/pkg/errors" "github.com/pkg/errors"
cmn "github.com/tendermint/tmlibs/common"
types "github.com/tendermint/tendermint/rpc/lib/types" types "github.com/tendermint/tendermint/rpc/lib/types"
wire "github.com/tendermint/go-wire" cmn "github.com/tendermint/tmlibs/common"
) )
const ( const (
@ -157,15 +156,15 @@ func (wsc *WSClient) Unsubscribe(eventid string) error {
func (wsc *WSClient) Call(method string, params map[string]interface{}) error { func (wsc *WSClient) Call(method string, params map[string]interface{}) error {
// we need this step because we attempt to decode values using `go-wire` // we need this step because we attempt to decode values using `go-wire`
// (handlers.go:470) on the server side // (handlers.go:470) on the server side
encodedParams := make(map[string]interface{}) // encodedParams := make(map[string]interface{})
for k, v := range params { // for k, v := range params {
bytes := json.RawMessage(wire.JSONBytes(v)) // bytes := json.RawMessage(wire.JSONBytes(v))
encodedParams[k] = &bytes // encodedParams[k] = &bytes
} // }
err := wsc.WriteJSON(types.RPCRequest{ err := wsc.WriteJSON(types.RPCRequest{
JSONRPC: "2.0", JSONRPC: "2.0",
Method: method, Method: method,
Params: encodedParams, Params: params,
ID: "", ID: "",
}) })
return err return err

View File

@ -3,6 +3,7 @@ package rpc
import ( import (
"bytes" "bytes"
crand "crypto/rand" crand "crypto/rand"
"encoding/json"
"fmt" "fmt"
"math/rand" "math/rand"
"net/http" "net/http"
@ -12,7 +13,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
wire "github.com/tendermint/go-wire" data "github.com/tendermint/go-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"
@ -29,7 +30,35 @@ const (
) )
// Define a type for results and register concrete versions // Define a type for results and register concrete versions
type Result interface{} type ResultInner interface{}
type Result struct {
ResultInner `json:"unwrap"`
}
func (r Result) MarshalJSON() ([]byte, error) {
return resultMapper.ToJSON(r.ResultInner)
}
func (r *Result) UnmarshalJSON(data []byte) (err error) {
parsed, err := resultMapper.FromJSON(data)
if err == nil && parsed != nil {
r.ResultInner = parsed.(ResultInner)
}
return
}
func (r Result) Unwrap() ResultInner {
tmrI := r.ResultInner
for wrap, ok := tmrI.(Result); ok; wrap, ok = tmrI.(Result) {
tmrI = wrap.ResultInner
}
return tmrI
}
func (r Result) Empty() bool {
return r.ResultInner == nil
}
type ResultEcho struct { type ResultEcho struct {
Value string Value string
@ -39,11 +68,9 @@ type ResultEchoBytes struct {
Value []byte Value []byte
} }
var _ = wire.RegisterInterface( var resultMapper = data.NewMapper(Result{}).
struct{ Result }{}, RegisterImplementation(&ResultEcho{}, "echo", 0x1).
wire.ConcreteType{&ResultEcho{}, 0x1}, RegisterImplementation(&ResultEchoBytes{}, "echo_bytes", 0x2)
wire.ConcreteType{&ResultEchoBytes{}, 0x2},
)
// Define some routes // Define some routes
var Routes = map[string]*server.RPCFunc{ var Routes = map[string]*server.RPCFunc{
@ -53,15 +80,15 @@ var Routes = map[string]*server.RPCFunc{
} }
func EchoResult(v string) (Result, error) { func EchoResult(v string) (Result, error) {
return &ResultEcho{v}, nil return Result{&ResultEcho{v}}, nil
} }
func EchoWSResult(wsCtx types.WSRPCContext, v string) (Result, error) { func EchoWSResult(wsCtx types.WSRPCContext, v string) (Result, error) {
return &ResultEcho{v}, nil return Result{&ResultEcho{v}}, nil
} }
func EchoBytesResult(v []byte) (Result, error) { func EchoBytesResult(v []byte) (Result, error) {
return &ResultEchoBytes{v}, nil return Result{&ResultEchoBytes{v}}, nil
} }
// launch unix and tcp servers // launch unix and tcp servers
@ -109,7 +136,7 @@ func echoViaHTTP(cl client.HTTPClient, val string) (string, error) {
if _, err := cl.Call("echo", params, &result); err != nil { if _, err := cl.Call("echo", params, &result); err != nil {
return "", err return "", err
} }
return result.(*ResultEcho).Value, nil return result.Unwrap().(*ResultEcho).Value, nil
} }
func echoBytesViaHTTP(cl client.HTTPClient, bytes []byte) ([]byte, error) { func echoBytesViaHTTP(cl client.HTTPClient, bytes []byte) ([]byte, error) {
@ -120,7 +147,7 @@ func echoBytesViaHTTP(cl client.HTTPClient, bytes []byte) ([]byte, error) {
if _, err := cl.Call("echo_bytes", params, &result); err != nil { if _, err := cl.Call("echo_bytes", params, &result); err != nil {
return []byte{}, err return []byte{}, err
} }
return result.(*ResultEchoBytes).Value, nil return result.Unwrap().(*ResultEchoBytes).Value, nil
} }
func testWithHTTPClient(t *testing.T, cl client.HTTPClient) { func testWithHTTPClient(t *testing.T, cl client.HTTPClient) {
@ -147,11 +174,11 @@ func echoViaWS(cl *client.WSClient, val string) (string, error) {
select { select {
case msg := <-cl.ResultsCh: case msg := <-cl.ResultsCh:
result := new(Result) result := new(Result)
wire.ReadJSONPtr(result, msg, &err) err = json.Unmarshal(msg, result)
if err != nil { if err != nil {
return "", nil return "", nil
} }
return (*result).(*ResultEcho).Value, nil return result.Unwrap().(*ResultEcho).Value, nil
case err := <-cl.ErrorsCh: case err := <-cl.ErrorsCh:
return "", err return "", err
} }
@ -169,11 +196,11 @@ func echoBytesViaWS(cl *client.WSClient, bytes []byte) ([]byte, error) {
select { select {
case msg := <-cl.ResultsCh: case msg := <-cl.ResultsCh:
result := new(Result) result := new(Result)
wire.ReadJSONPtr(result, msg, &err) err = json.Unmarshal(msg, result)
if err != nil { if err != nil {
return []byte{}, nil return []byte{}, nil
} }
return (*result).(*ResultEchoBytes).Value, nil return result.Unwrap().(*ResultEchoBytes).Value, nil
case err := <-cl.ErrorsCh: case err := <-cl.ErrorsCh:
return []byte{}, err return []byte{}, err
} }
@ -252,9 +279,9 @@ func TestWSNewWSRPCFunc(t *testing.T) {
select { select {
case msg := <-cl.ResultsCh: case msg := <-cl.ResultsCh:
result := new(Result) result := new(Result)
wire.ReadJSONPtr(result, msg, &err) err = json.Unmarshal(msg, result)
require.Nil(t, err) require.Nil(t, err)
got := (*result).(*ResultEcho).Value got := result.Unwrap().(*ResultEcho).Value
assert.Equal(t, got, val) assert.Equal(t, got, val)
case err := <-cl.ErrorsCh: case err := <-cl.ErrorsCh:
t.Fatal(err) t.Fatal(err)
@ -280,9 +307,9 @@ func TestWSHandlesArrayParams(t *testing.T) {
select { select {
case msg := <-cl.ResultsCh: case msg := <-cl.ResultsCh:
result := new(Result) result := new(Result)
wire.ReadJSONPtr(result, msg, &err) err = json.Unmarshal(msg, result)
require.Nil(t, err) require.Nil(t, err)
got := (*result).(*ResultEcho).Value got := result.Unwrap().(*ResultEcho).Value
assert.Equal(t, got, val) assert.Equal(t, got, val)
case err := <-cl.ErrorsCh: case err := <-cl.ErrorsCh:
t.Fatalf("%+v", err) t.Fatalf("%+v", err)

View File

@ -280,9 +280,8 @@ func httpParamsToArgs(rpcFunc *RPCFunc, r *http.Request) ([]reflect.Value, error
} }
func _jsonStringToArg(ty reflect.Type, arg string) (reflect.Value, error) { func _jsonStringToArg(ty reflect.Type, arg string) (reflect.Value, error) {
var err error
v := reflect.New(ty) v := reflect.New(ty)
wire.ReadJSONPtr(v.Interface(), []byte(arg), &err) err := json.Unmarshal([]byte(arg), v.Interface())
if err != nil { if err != nil {
return v, err return v, err
} }
@ -315,9 +314,8 @@ func nonJsonToArg(ty reflect.Type, arg string) (reflect.Value, error, bool) {
} }
if isQuotedString && expectingByteSlice { if isQuotedString && expectingByteSlice {
var err error
v := reflect.New(reflect.TypeOf("")) v := reflect.New(reflect.TypeOf(""))
wire.ReadJSONPtr(v.Interface(), []byte(arg), &err) err := json.Unmarshal([]byte(arg), v.Interface())
if err != nil { if err != nil {
return reflect.ValueOf(nil), err, false return reflect.ValueOf(nil), err, false
} }

View File

@ -4,7 +4,6 @@ import (
"encoding/json" "encoding/json"
"strings" "strings"
wire "github.com/tendermint/go-wire"
events "github.com/tendermint/tmlibs/events" events "github.com/tendermint/tmlibs/events"
) )
@ -52,8 +51,14 @@ type RPCResponse struct {
func NewRPCResponse(id string, res interface{}, err string) RPCResponse { func NewRPCResponse(id string, res interface{}, err string) RPCResponse {
var raw *json.RawMessage var raw *json.RawMessage
if res != nil { if res != nil {
rawMsg := json.RawMessage(wire.JSONBytes(res)) var js []byte
raw = &rawMsg js, err2 := json.Marshal(res)
if err2 == nil {
rawMsg := json.RawMessage(js)
raw = &rawMsg
} else {
err = err2.Error()
}
} }
return RPCResponse{ return RPCResponse{
JSONRPC: "2.0", JSONRPC: "2.0",

View File

@ -1,6 +1,7 @@
package rpctest package rpctest
import ( import (
"encoding/json"
"fmt" "fmt"
"math/rand" "math/rand"
"os" "os"
@ -11,7 +12,6 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
wire "github.com/tendermint/go-wire"
logger "github.com/tendermint/tmlibs/logger" logger "github.com/tendermint/tmlibs/logger"
abci "github.com/tendermint/abci/types" abci "github.com/tendermint/abci/types"
@ -132,7 +132,7 @@ func waitForEvent(t *testing.T, wsc *client.WSClient, eventid string, dieOnTimeo
select { select {
case r := <-wsc.ResultsCh: case r := <-wsc.ResultsCh:
result := new(ctypes.TMResult) result := new(ctypes.TMResult)
wire.ReadJSONPtr(result, r, &err) err = json.Unmarshal(r, result)
if err != nil { if err != nil {
errCh <- err errCh <- err
break LOOP break LOOP