diff --git a/binary/binary.go b/binary/binary.go index 2fb4bf34a..5632ac69b 100644 --- a/binary/binary.go +++ b/binary/binary.go @@ -25,19 +25,23 @@ func WriteBinary(o interface{}, w io.Writer, n *int64, err *error) { } func ReadJSON(o interface{}, bytes []byte, err *error) interface{} { - var parsed interface{} - *err = json.Unmarshal(bytes, &parsed) + var object interface{} + *err = json.Unmarshal(bytes, &object) if *err != nil { return o } + return ReadJSONFromObject(o, object, err) +} + +func ReadJSONFromObject(o interface{}, object interface{}, err *error) interface{} { rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) if rv.Kind() == reflect.Ptr { - readReflectJSON(rv.Elem(), rt.Elem(), parsed, err) + readReflectJSON(rv.Elem(), rt.Elem(), object, err) return o } else { ptrRv := reflect.New(rt) - readReflectJSON(ptrRv.Elem(), rt, parsed, err) + readReflectJSON(ptrRv.Elem(), rt, object, err) return ptrRv.Elem().Interface() } } diff --git a/p2p/pex_reactor.go b/p2p/pex_reactor.go index 5ba238d31..6af070589 100644 --- a/p2p/pex_reactor.go +++ b/p2p/pex_reactor.go @@ -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 { Network string diff --git a/rpc/http_handlers.go b/rpc/http_handlers.go index 225561360..10e981dc1 100644 --- a/rpc/http_handlers.go +++ b/rpc/http_handlers.go @@ -1,7 +1,6 @@ package rpc import ( - "encoding/hex" "encoding/json" "fmt" "github.com/tendermint/tendermint/binary" @@ -9,7 +8,6 @@ import ( "io/ioutil" "net/http" "reflect" - "strconv" ) // 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 func jsonToArg(ty reflect.Type, arg string) (reflect.Value, error) { - v := reflect.New(ty).Elem() - kind := v.Kind() var err error - switch kind { - case reflect.Interface: - v = reflect.New(ty) - binary.ReadJSON(v.Interface(), []byte(arg), &err) - if err != nil { - return v, err - } - v = v.Elem() - case reflect.Struct: - binary.ReadJSON(v.Interface(), []byte(arg), &err) - if err != nil { - return v, err - } - case reflect.Slice: - rt := ty.Elem() - 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 { - return v, err - } - 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) + v := reflect.New(ty) + binary.ReadJSON(v.Interface(), []byte(arg), &err) + if err != nil { + return v, err + } + v = v.Elem() + return v, nil +} + +func jsonObjectToArg(ty reflect.Type, object interface{}) (reflect.Value, error) { + var err error + v := reflect.New(ty) + binary.ReadJSONFromObject(v.Interface(), object, &err) + if err != nil { + return v, err } + v = v.Elem() return v, nil } @@ -145,6 +96,7 @@ func queryToValues(funcInfo *FuncWrapper, r *http.Request) ([]reflect.Value, err for i, name := range argNames { ty := argTypes[i] arg := GetParam(r, name) + //fmt.Println("GetParam()", r, name, arg) values[i], err = jsonToArg(ty, arg) if err != nil { 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 -// TODO! -func paramsToValues(funcInfo *FuncWrapper, params []string) ([]reflect.Value, error) { +func paramsToValues(funcInfo *FuncWrapper, params []interface{}) ([]reflect.Value, error) { values := make([]reflect.Value, len(params)) for i, p := range params { ty := funcInfo.args[i] - v, err := jsonToArg(ty, p) + v, err := jsonObjectToArg(ty, p) if err != nil { return nil, err } @@ -249,10 +200,10 @@ func initHandlers() { } type JsonRpc struct { - JsonRpc string `json:"jsonrpc"` - Method string `json:"method"` - Params []string `json:"params"` - Id int `json:"id"` + JsonRpc string `json:"jsonrpc"` + Method string `json:"method"` + Params []interface{} `json:"params"` + Id int `json:"id"` } // this will panic if not passed a function diff --git a/rpc/test/http_rpc_test.go b/rpc/test/http_rpc_test.go index 3021584c3..fa0eb29c7 100644 --- a/rpc/test/http_rpc_test.go +++ b/rpc/test/http_rpc_test.go @@ -71,6 +71,9 @@ func TestHTTPGenPriv(t *testing.T) { func TestHTTPGetAccount(t *testing.T) { byteAddr, _ := hex.DecodeString(userAddr) acc := getAccount(t, "HTTP", byteAddr) + if acc == nil { + t.Fatalf("Account was nil") + } if bytes.Compare(acc.Address, byteAddr) != 0 { t.Fatalf("Failed to get correct account. Got %x, expected %x", acc.Address, byteAddr) } diff --git a/rpc/test/json_rpc_test.go b/rpc/test/json_rpc_test.go index 3b857f24e..e0f15150f 100644 --- a/rpc/test/json_rpc_test.go +++ b/rpc/test/json_rpc_test.go @@ -21,7 +21,7 @@ func TestJSONStatus(t *testing.T) { s := rpc.JsonRpc{ JsonRpc: "2.0", Method: "status", - Params: []string{}, + Params: []interface{}{}, Id: 0, } b, err := json.Marshal(s) @@ -56,7 +56,7 @@ func TestJSONGenPriv(t *testing.T) { s := rpc.JsonRpc{ JsonRpc: "2.0", Method: "unsafe/gen_priv_account", - Params: []string{}, + Params: []interface{}{}, Id: 0, } b, err := json.Marshal(s) diff --git a/rpc/test/test.go b/rpc/test/test.go index 45a5f412a..37420e5f9 100644 --- a/rpc/test/test.go +++ b/rpc/test/test.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/hex" "encoding/json" - "fmt" "github.com/tendermint/tendermint/account" "github.com/tendermint/tendermint/binary" "github.com/tendermint/tendermint/config" @@ -24,8 +23,6 @@ var ( rpcAddr = "127.0.0.1:8089" requestAddr = "http://" + rpcAddr + "/" - chainId string - node *daemon.Node mempoolCount = 0 @@ -78,7 +75,7 @@ func getAccount(t *testing.T, typ string, addr []byte) *account.Account { s := rpc.JsonRpc{ JsonRpc: "2.0", Method: "get_account", - Params: []string{"0x" + hex.EncodeToString(addr)}, + Params: []interface{}{hex.EncodeToString(addr)}, Id: 0, } 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) case "HTTP": 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 { t.Fatal(err) } @@ -105,7 +101,6 @@ func getAccount(t *testing.T, typ string, addr []byte) *account.Account { Data core.ResponseGetAccount Error string } - fmt.Println(string(body)) binary.ReadJSON(&status, body, &err) if err != nil { t.Fatal(err) @@ -153,7 +148,6 @@ func requestResponse(t *testing.T, method string, values url.Values, status inte if err != nil { t.Fatal(err) } - fmt.Println(string(body)) binary.ReadJSON(status, body, &err) if err != nil { 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 { t.Fatal(err) } - fmt.Println(priv.PubKey, in.PubKey) // Check signatures // acc := getAccount(t, byteAddr) // NOTE: using the acc here instead of the in fails; its PubKeyNil ... ?