diff --git a/rpc/tendermint/client/client.go b/rpc/tendermint/client/client.go index a696389c7c348b122cabd919924f79d386d3dec6..601b1fb4d0f05730a9dd731b8858d53c0c138f97 100644 --- a/rpc/tendermint/client/client.go +++ b/rpc/tendermint/client/client.go @@ -1,6 +1,7 @@ package client import ( + "fmt" acm "github.com/eris-ltd/eris-db/account" core_types "github.com/eris-ltd/eris-db/core/types" rpc_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types" @@ -10,14 +11,7 @@ import ( ) func Status(client rpcclient.Client) (*rpc_types.ResultStatus, error) { - var res rpc_types.ErisDBResult //ResultStatus) - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("status", []interface{}{}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("status", map[string]interface{}{}, &res) - } + res, err := performCall(client, "status") if err != nil { return nil, err } @@ -25,30 +19,16 @@ func Status(client rpcclient.Client) (*rpc_types.ResultStatus, error) { } func GenPrivAccount(client rpcclient.Client) (*acm.PrivAccount, error) { - var res rpc_types.ErisDBResult - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("unsafe/gen_priv_account", []interface{}{}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("unsafe/gen_priv_account", map[string]interface{}{}, &res) - } + res, err := performCall(client, "unsafe/gen_priv_account") if err != nil { return nil, err } return res.(*rpc_types.ResultGenPrivAccount).PrivAccount, nil } -func GetAccount(client rpcclient.Client, addr []byte) (*acm.Account, error) { - var res rpc_types.ErisDBResult - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("get_account", []interface{}{addr}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("get_account", map[string]interface{}{"address": addr}, - &res) - } +func GetAccount(client rpcclient.Client, address []byte) (*acm.Account, error) { + res, err := performCall(client, "get_account", + "address", address) if err != nil { return nil, err } @@ -56,21 +36,10 @@ func GetAccount(client rpcclient.Client, addr []byte) (*acm.Account, error) { } func SignTx(client rpcclient.Client, tx txs.Tx, - privAccs []*acm.PrivAccount) (txs.Tx, error) { - wrapTx := struct { - txs.Tx `json:"unwrap"` - }{tx} - var res rpc_types.ErisDBResult - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("unsafe/sign_tx", []interface{}{wrapTx, privAccs}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("unsafe/sign_tx", map[string]interface{}{ - "tx": wrapTx, - "privAccounts": privAccs, - }, &res) - } + privAccounts []*acm.PrivAccount) (txs.Tx, error) { + res, err := performCall(client, "unsafe/sign_tx", + "tx", wrappedTx{tx}, + "privAccounts", privAccounts) if err != nil { return nil, err } @@ -79,18 +48,8 @@ func SignTx(client rpcclient.Client, tx txs.Tx, func BroadcastTx(client rpcclient.Client, tx txs.Tx) (txs.Receipt, error) { - wrapTx := struct { - txs.Tx `json:"unwrap"` - }{tx} - var res rpc_types.ErisDBResult - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("broadcast_tx", []interface{}{wrapTx}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("broadcast_tx", map[string]interface{}{"tx": wrapTx}, - &res) - } + res, err := performCall(client, "broadcast_tx", + "tx", wrappedTx{tx}) if err != nil { return txs.Receipt{}, err } @@ -102,55 +61,31 @@ func BroadcastTx(client rpcclient.Client, } func DumpStorage(client rpcclient.Client, - addr []byte) (*rpc_types.ResultDumpStorage, error) { - var res rpc_types.ErisDBResult - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("dump_storage", []interface{}{addr}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("dump_storage", map[string]interface{}{"address": addr}, - &res) - } + address []byte) (*rpc_types.ResultDumpStorage, error) { + res, err := performCall(client, "dump_storage", + "address", address) if err != nil { return nil, err } return res.(*rpc_types.ResultDumpStorage), err } -func GetStorage(client rpcclient.Client, addr, key []byte) ([]byte, error) { - var res rpc_types.ErisDBResult - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("get_storage", []interface{}{addr, key}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("get_storage", map[string]interface{}{ - "address": addr, - "key": key, - }, &res) - } +func GetStorage(client rpcclient.Client, address, key []byte) ([]byte, error) { + res, err := performCall(client, "get_storage", + "address", address, + "key", key) if err != nil { return nil, err } return res.(*rpc_types.ResultGetStorage).Value, nil } -func CallCode(client rpcclient.Client, - fromAddress, code, data []byte) (*rpc_types.ResultCall, error) { - var res rpc_types.ErisDBResult - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("call_code", []interface{}{fromAddress, code, data}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("call_code", map[string]interface{}{ - "fromAddress": fromAddress, - "code": code, - "data": data, - }, &res) - - } +func CallCode(client rpcclient.Client, fromAddress, code, + data []byte) (*rpc_types.ResultCall, error) { + res, err := performCall(client, "call_code", + "fromAddress", fromAddress, + "code", code, + "data", data) if err != nil { return nil, err } @@ -159,19 +94,10 @@ func CallCode(client rpcclient.Client, func Call(client rpcclient.Client, fromAddress, toAddress, data []byte) (*rpc_types.ResultCall, error) { - var res rpc_types.ErisDBResult - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("call", []interface{}{fromAddress, toAddress, data}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("call", map[string]interface{}{ - "fromAddress": fromAddress, - "toAddress": toAddress, - "data": data, - }, &res) - - } + res, err := performCall(client, "call", + "fromAddress", fromAddress, + "toAddress", toAddress, + "data", data) if err != nil { return nil, err } @@ -179,16 +105,57 @@ func Call(client rpcclient.Client, fromAddress, toAddress, } func GetName(client rpcclient.Client, name string) (*core_types.NameRegEntry, error) { - var res rpc_types.ErisDBResult - var err error - switch cli := client.(type) { - case *rpcclient.ClientJSONRPC: - _, err = cli.Call("get_name", []interface{}{name}, &res) - case *rpcclient.ClientURI: - _, err = cli.Call("get_name", map[string]interface{}{"name": name}, &res) - } + res, err := performCall(client, "get_name", + "name", name) if err != nil { return nil, err } return res.(*rpc_types.ResultGetName).Entry, nil } + +func BlockchainInfo(client rpcclient.Client, minHeight, + maxHeight int) (*rpc_types.ResultBlockchainInfo, error) { + res, err := performCall(client, "blockchain", + "minHeight", minHeight, + "maxHeight", maxHeight) + if err != nil { + return nil, err + } + return res.(*rpc_types.ResultBlockchainInfo), err +} + +func performCall(client rpcclient.Client, method string, + paramKeyVals ...interface{}) (res rpc_types.ErisDBResult, err error) { + paramsMap, paramsSlice := mapAndValues(paramKeyVals...) + switch cli := client.(type) { + case *rpcclient.ClientJSONRPC: + _, err = cli.Call(method, paramsSlice, &res) + case *rpcclient.ClientURI: + _, err = cli.Call(method, paramsMap, &res) + } + return res, err + +} +func mapAndValues(orderedKeyVals ...interface{}) (map[string]interface{}, []interface{}) { + if len(orderedKeyVals)%2 != 0 { + panic(fmt.Sprintf("mapAndValues requires a even length list of keys and "+ + "values but got: %v (length %v)", + orderedKeyVals, len(orderedKeyVals))) + } + paramsMap := make(map[string]interface{}) + paramsSlice := make([]interface{}, len(orderedKeyVals)/2) + for i := 0; i < len(orderedKeyVals); i += 2 { + key, ok := orderedKeyVals[i].(string) + if !ok { + panic("mapAndValues requires every even element of orderedKeyVals to be a string key") + } + val := orderedKeyVals[i+1] + paramsMap[key] = val + paramsSlice = append(paramsSlice, val) + } + return paramsMap, paramsSlice +} + +type wrappedTx struct { + txs.Tx `json:"unwrap"` +}