When using JSONRPC, do not double-encode JSON.
This commit is contained in:
parent
ffa82b5c61
commit
1a4aab4c35
|
@ -25,19 +25,23 @@ func WriteBinary(o interface{}, w io.Writer, n *int64, err *error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadJSON(o interface{}, bytes []byte, err *error) interface{} {
|
func ReadJSON(o interface{}, bytes []byte, err *error) interface{} {
|
||||||
var parsed interface{}
|
var object interface{}
|
||||||
*err = json.Unmarshal(bytes, &parsed)
|
*err = json.Unmarshal(bytes, &object)
|
||||||
if *err != nil {
|
if *err != nil {
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ReadJSONFromObject(o, object, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadJSONFromObject(o interface{}, object interface{}, err *error) interface{} {
|
||||||
rv, rt := reflect.ValueOf(o), reflect.TypeOf(o)
|
rv, rt := reflect.ValueOf(o), reflect.TypeOf(o)
|
||||||
if rv.Kind() == reflect.Ptr {
|
if rv.Kind() == reflect.Ptr {
|
||||||
readReflectJSON(rv.Elem(), rt.Elem(), parsed, err)
|
readReflectJSON(rv.Elem(), rt.Elem(), object, err)
|
||||||
return o
|
return o
|
||||||
} else {
|
} else {
|
||||||
ptrRv := reflect.New(rt)
|
ptrRv := reflect.New(rt)
|
||||||
readReflectJSON(ptrRv.Elem(), rt, parsed, err)
|
readReflectJSON(ptrRv.Elem(), rt, object, err)
|
||||||
return ptrRv.Elem().Interface()
|
return ptrRv.Elem().Interface()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,7 +237,7 @@ func DecodeMessage(bz []byte) (msg interface{}, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A pexHandshakeMessage contains the peer's chainId
|
A pexHandshakeMessage contains the network identifier.
|
||||||
*/
|
*/
|
||||||
type pexHandshakeMessage struct {
|
type pexHandshakeMessage struct {
|
||||||
Network string
|
Network string
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package rpc
|
package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/tendermint/tendermint/binary"
|
"github.com/tendermint/tendermint/binary"
|
||||||
|
@ -9,7 +8,6 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// cache all type information about each function up front
|
// cache all type information about each function up front
|
||||||
|
@ -66,71 +64,24 @@ func toHandler(funcName string) func(http.ResponseWriter, *http.Request) {
|
||||||
|
|
||||||
// convert a (json) string to a given type
|
// convert a (json) string to a given type
|
||||||
func jsonToArg(ty reflect.Type, arg string) (reflect.Value, error) {
|
func jsonToArg(ty reflect.Type, arg string) (reflect.Value, error) {
|
||||||
v := reflect.New(ty).Elem()
|
|
||||||
kind := v.Kind()
|
|
||||||
var err error
|
var err error
|
||||||
switch kind {
|
v := reflect.New(ty)
|
||||||
case reflect.Interface:
|
|
||||||
v = reflect.New(ty)
|
|
||||||
binary.ReadJSON(v.Interface(), []byte(arg), &err)
|
binary.ReadJSON(v.Interface(), []byte(arg), &err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
v = v.Elem()
|
v = v.Elem()
|
||||||
case reflect.Struct:
|
return v, nil
|
||||||
binary.ReadJSON(v.Interface(), []byte(arg), &err)
|
}
|
||||||
if err != nil {
|
|
||||||
return v, err
|
func jsonObjectToArg(ty reflect.Type, object interface{}) (reflect.Value, error) {
|
||||||
}
|
var err error
|
||||||
case reflect.Slice:
|
v := reflect.New(ty)
|
||||||
rt := ty.Elem()
|
binary.ReadJSONFromObject(v.Interface(), object, &err)
|
||||||
if rt.Kind() == reflect.Uint8 {
|
|
||||||
// if hex, decode
|
|
||||||
if len(arg) > 2 && arg[:2] == "0x" {
|
|
||||||
arg = arg[2:]
|
|
||||||
b, err := hex.DecodeString(arg)
|
|
||||||
if err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
v = reflect.ValueOf(b)
|
|
||||||
} else {
|
|
||||||
v = reflect.ValueOf([]byte(arg))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v = reflect.New(ty)
|
|
||||||
binary.ReadJSON(v.Interface(), []byte(arg), &err)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
v = v.Elem()
|
v = v.Elem()
|
||||||
}
|
|
||||||
case reflect.Int64:
|
|
||||||
u, err := strconv.ParseInt(arg, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
v = reflect.ValueOf(u)
|
|
||||||
case reflect.Int32:
|
|
||||||
u, err := strconv.ParseInt(arg, 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
v = reflect.ValueOf(u)
|
|
||||||
case reflect.Uint64:
|
|
||||||
u, err := strconv.ParseUint(arg, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
v = reflect.ValueOf(u)
|
|
||||||
case reflect.Uint:
|
|
||||||
u, err := strconv.ParseUint(arg, 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
v = reflect.ValueOf(u)
|
|
||||||
default:
|
|
||||||
v = reflect.ValueOf(arg)
|
|
||||||
}
|
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +96,7 @@ func queryToValues(funcInfo *FuncWrapper, r *http.Request) ([]reflect.Value, err
|
||||||
for i, name := range argNames {
|
for i, name := range argNames {
|
||||||
ty := argTypes[i]
|
ty := argTypes[i]
|
||||||
arg := GetParam(r, name)
|
arg := GetParam(r, name)
|
||||||
|
//fmt.Println("GetParam()", r, name, arg)
|
||||||
values[i], err = jsonToArg(ty, arg)
|
values[i], err = jsonToArg(ty, arg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -154,12 +106,11 @@ func queryToValues(funcInfo *FuncWrapper, r *http.Request) ([]reflect.Value, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// covert a list of interfaces to properly typed values
|
// covert a list of interfaces to properly typed values
|
||||||
// TODO!
|
func paramsToValues(funcInfo *FuncWrapper, params []interface{}) ([]reflect.Value, error) {
|
||||||
func paramsToValues(funcInfo *FuncWrapper, params []string) ([]reflect.Value, error) {
|
|
||||||
values := make([]reflect.Value, len(params))
|
values := make([]reflect.Value, len(params))
|
||||||
for i, p := range params {
|
for i, p := range params {
|
||||||
ty := funcInfo.args[i]
|
ty := funcInfo.args[i]
|
||||||
v, err := jsonToArg(ty, p)
|
v, err := jsonObjectToArg(ty, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -251,7 +202,7 @@ func initHandlers() {
|
||||||
type JsonRpc struct {
|
type JsonRpc struct {
|
||||||
JsonRpc string `json:"jsonrpc"`
|
JsonRpc string `json:"jsonrpc"`
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Params []string `json:"params"`
|
Params []interface{} `json:"params"`
|
||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,9 @@ func TestHTTPGenPriv(t *testing.T) {
|
||||||
func TestHTTPGetAccount(t *testing.T) {
|
func TestHTTPGetAccount(t *testing.T) {
|
||||||
byteAddr, _ := hex.DecodeString(userAddr)
|
byteAddr, _ := hex.DecodeString(userAddr)
|
||||||
acc := getAccount(t, "HTTP", byteAddr)
|
acc := getAccount(t, "HTTP", byteAddr)
|
||||||
|
if acc == nil {
|
||||||
|
t.Fatalf("Account was nil")
|
||||||
|
}
|
||||||
if bytes.Compare(acc.Address, byteAddr) != 0 {
|
if bytes.Compare(acc.Address, byteAddr) != 0 {
|
||||||
t.Fatalf("Failed to get correct account. Got %x, expected %x", acc.Address, byteAddr)
|
t.Fatalf("Failed to get correct account. Got %x, expected %x", acc.Address, byteAddr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ func TestJSONStatus(t *testing.T) {
|
||||||
s := rpc.JsonRpc{
|
s := rpc.JsonRpc{
|
||||||
JsonRpc: "2.0",
|
JsonRpc: "2.0",
|
||||||
Method: "status",
|
Method: "status",
|
||||||
Params: []string{},
|
Params: []interface{}{},
|
||||||
Id: 0,
|
Id: 0,
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(s)
|
b, err := json.Marshal(s)
|
||||||
|
@ -56,7 +56,7 @@ func TestJSONGenPriv(t *testing.T) {
|
||||||
s := rpc.JsonRpc{
|
s := rpc.JsonRpc{
|
||||||
JsonRpc: "2.0",
|
JsonRpc: "2.0",
|
||||||
Method: "unsafe/gen_priv_account",
|
Method: "unsafe/gen_priv_account",
|
||||||
Params: []string{},
|
Params: []interface{}{},
|
||||||
Id: 0,
|
Id: 0,
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(s)
|
b, err := json.Marshal(s)
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"github.com/tendermint/tendermint/account"
|
"github.com/tendermint/tendermint/account"
|
||||||
"github.com/tendermint/tendermint/binary"
|
"github.com/tendermint/tendermint/binary"
|
||||||
"github.com/tendermint/tendermint/config"
|
"github.com/tendermint/tendermint/config"
|
||||||
|
@ -24,8 +23,6 @@ var (
|
||||||
rpcAddr = "127.0.0.1:8089"
|
rpcAddr = "127.0.0.1:8089"
|
||||||
requestAddr = "http://" + rpcAddr + "/"
|
requestAddr = "http://" + rpcAddr + "/"
|
||||||
|
|
||||||
chainId string
|
|
||||||
|
|
||||||
node *daemon.Node
|
node *daemon.Node
|
||||||
|
|
||||||
mempoolCount = 0
|
mempoolCount = 0
|
||||||
|
@ -78,7 +75,7 @@ func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
|
||||||
s := rpc.JsonRpc{
|
s := rpc.JsonRpc{
|
||||||
JsonRpc: "2.0",
|
JsonRpc: "2.0",
|
||||||
Method: "get_account",
|
Method: "get_account",
|
||||||
Params: []string{"0x" + hex.EncodeToString(addr)},
|
Params: []interface{}{hex.EncodeToString(addr)},
|
||||||
Id: 0,
|
Id: 0,
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(s)
|
b, err := json.Marshal(s)
|
||||||
|
@ -89,9 +86,8 @@ func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
|
||||||
resp, err = http.Post(requestAddr, "text/json", buf)
|
resp, err = http.Post(requestAddr, "text/json", buf)
|
||||||
case "HTTP":
|
case "HTTP":
|
||||||
resp, err = http.PostForm(requestAddr+"get_account",
|
resp, err = http.PostForm(requestAddr+"get_account",
|
||||||
url.Values{"address": {string(addr)}})
|
url.Values{"address": {"\"" + (hex.EncodeToString(addr)) + "\""}})
|
||||||
}
|
}
|
||||||
fmt.Println("RESPONSE:", resp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -105,7 +101,6 @@ func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
|
||||||
Data core.ResponseGetAccount
|
Data core.ResponseGetAccount
|
||||||
Error string
|
Error string
|
||||||
}
|
}
|
||||||
fmt.Println(string(body))
|
|
||||||
binary.ReadJSON(&status, body, &err)
|
binary.ReadJSON(&status, body, &err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -153,7 +148,6 @@ func requestResponse(t *testing.T, method string, values url.Values, status inte
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
fmt.Println(string(body))
|
|
||||||
binary.ReadJSON(status, body, &err)
|
binary.ReadJSON(status, body, &err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -206,7 +200,6 @@ func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types
|
||||||
if err := in.ValidateBasic(); err != nil {
|
if err := in.ValidateBasic(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
fmt.Println(priv.PubKey, in.PubKey)
|
|
||||||
// Check signatures
|
// Check signatures
|
||||||
// acc := getAccount(t, byteAddr)
|
// acc := getAccount(t, byteAddr)
|
||||||
// NOTE: using the acc here instead of the in fails; its PubKeyNil ... ?
|
// NOTE: using the acc here instead of the in fails; its PubKeyNil ... ?
|
||||||
|
|
Loading…
Reference in New Issue