From 731de7a6aaec12eb4f1ab75e0aed01fff103ce6e Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 28 Mar 2015 23:10:05 -0700 Subject: [PATCH] rpc: return (*Response, error) for all functions --- rpc/core/accounts.go | 12 ++++++------ rpc/core/blocks.go | 12 ++++++------ rpc/core/mempool.go | 6 +++--- rpc/core/net.go | 8 ++++---- rpc/{ => core}/responses.go | 5 ++--- rpc/core/txs.go | 4 ++-- rpc/core/validators.go | 4 ++-- rpc/http_handlers.go | 36 ++++++++++++++++++++++-------------- rpc/test/http_rpc_test.go | 8 ++++---- rpc/test/json_rpc_test.go | 7 ++++--- rpc/test/test.go | 5 +++-- 11 files changed, 58 insertions(+), 49 deletions(-) rename rpc/{ => core}/responses.go (93%) diff --git a/rpc/core/accounts.go b/rpc/core/accounts.go index b70fa1874..84ffc2ee4 100644 --- a/rpc/core/accounts.go +++ b/rpc/core/accounts.go @@ -6,20 +6,20 @@ import ( //----------------------------------------------------------------------------- -func GenPrivAccount() *account.PrivAccount { - return account.GenPrivAccount() +func GenPrivAccount() (*ResponseGenPrivAccount, error) { + return &ResponseGenPrivAccount{account.GenPrivAccount()}, nil } //----------------------------------------------------------------------------- -func GetAccount(address []byte) *account.Account { +func GetAccount(address []byte) (*ResponseGetAccount, error) { state := consensusState.GetState() - return state.GetAccount(address) + return &ResponseGetAccount{state.GetAccount(address)}, nil } //----------------------------------------------------------------------------- -func ListAccounts() (uint, []*account.Account) { +func ListAccounts() (*ResponseListAccounts, error) { var blockHeight uint var accounts []*account.Account state := consensusState.GetState() @@ -28,5 +28,5 @@ func ListAccounts() (uint, []*account.Account) { accounts = append(accounts, value.(*account.Account)) return false }) - return blockHeight, accounts + return &ResponseListAccounts{blockHeight, accounts}, nil } diff --git a/rpc/core/blocks.go b/rpc/core/blocks.go index 84e7b53b0..4bbe716c0 100644 --- a/rpc/core/blocks.go +++ b/rpc/core/blocks.go @@ -8,7 +8,7 @@ import ( //----------------------------------------------------------------------------- -func BlockchainInfo(minHeight, maxHeight uint) (uint, []*types.BlockMeta) { +func BlockchainInfo(minHeight, maxHeight uint) (*ResponseBlockchainInfo, error) { if maxHeight == 0 { maxHeight = blockStore.Height() } else { @@ -25,20 +25,20 @@ func BlockchainInfo(minHeight, maxHeight uint) (uint, []*types.BlockMeta) { blockMetas = append(blockMetas, blockMeta) } - return blockStore.Height(), blockMetas + return &ResponseBlockchainInfo{blockStore.Height(), blockMetas}, nil } //----------------------------------------------------------------------------- -func GetBlock(height uint) (*types.BlockMeta, *types.Block, error) { +func GetBlock(height uint) (*ResponseGetBlock, error) { if height == 0 { - return nil, nil, fmt.Errorf("height must be greater than 1") + return nil, fmt.Errorf("height must be greater than 1") } if height > blockStore.Height() { - return nil, nil, fmt.Errorf("height must be less than the current blockchain height") + return nil, fmt.Errorf("height must be less than the current blockchain height") } blockMeta := blockStore.LoadBlockMeta(height) block := blockStore.LoadBlock(height) - return blockMeta, block, nil + return &ResponseGetBlock{blockMeta, block}, nil } diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 148cb84c3..3ff1a85ea 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -18,10 +18,10 @@ type Receipt struct { // pass pointer? // Note: tx must be signed -func BroadcastTx(tx types.Tx) (Receipt, error) { +func BroadcastTx(tx types.Tx) (*ResponseBroadcastTx, error) { err := mempoolReactor.BroadcastTx(tx) if err != nil { - return Receipt{}, fmt.Errorf("Error broadcasting transaction: %v", err) + return nil, fmt.Errorf("Error broadcasting transaction: %v", err) } txHash := merkle.HashFromBinary(tx) @@ -34,7 +34,7 @@ func BroadcastTx(tx types.Tx) (Receipt, error) { contractAddr = state.NewContractAddress(callTx.Input.Address, uint64(callTx.Input.Sequence)) } } - return Receipt{txHash, createsContract, contractAddr}, nil + return &ResponseBroadcastTx{Receipt{txHash, createsContract, contractAddr}}, nil } /* diff --git a/rpc/core/net.go b/rpc/core/net.go index b143d7271..64db01cfa 100644 --- a/rpc/core/net.go +++ b/rpc/core/net.go @@ -9,7 +9,7 @@ import ( //----------------------------------------------------------------------------- -func Status() ([]byte, string, []byte, uint, int64) { +func Status() (*ResponseStatus, error) { db := dbm.NewMemDB() genesisState := sm.MakeGenesisStateFromFile(db, config.App().GetString("GenesisFile")) genesisHash := genesisState.Hash() @@ -25,15 +25,15 @@ func Status() ([]byte, string, []byte, uint, int64) { latestBlockTime = latestBlockMeta.Header.Time.UnixNano() } - return genesisHash, config.App().GetString("Network"), latestBlockHash, latestHeight, latestBlockTime + return &ResponseStatus{genesisHash, config.App().GetString("Network"), latestBlockHash, latestHeight, latestBlockTime}, nil } //----------------------------------------------------------------------------- -func NetInfo() (int, bool, string) { +func NetInfo() (*ResponseNetInfo, error) { o, i, _ := p2pSwitch.NumPeers() numPeers := o + i listening := p2pSwitch.IsListening() network := config.App().GetString("Network") - return numPeers, listening, network + return &ResponseNetInfo{numPeers, listening, network}, nil } diff --git a/rpc/responses.go b/rpc/core/responses.go similarity index 93% rename from rpc/responses.go rename to rpc/core/responses.go index 11360c004..3e6e32e6a 100644 --- a/rpc/responses.go +++ b/rpc/core/responses.go @@ -1,8 +1,7 @@ -package rpc +package core import ( "github.com/tendermint/tendermint/account" - "github.com/tendermint/tendermint/rpc/core" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" ) @@ -32,7 +31,7 @@ type ResponseGetBlock struct { // curl -H 'content-type: text/plain;' http://127.0.0.1:8888/submit_tx?tx=... type ResponseBroadcastTx struct { - Receipt core.Receipt + Receipt Receipt } type ResponseStatus struct { diff --git a/rpc/core/txs.go b/rpc/core/txs.go index 670984394..95b9fb552 100644 --- a/rpc/core/txs.go +++ b/rpc/core/txs.go @@ -8,7 +8,7 @@ import ( //----------------------------------------------------------------------------- -func SignTx(tx types.Tx, privAccounts []*account.PrivAccount) (types.Tx, error) { +func SignTx(tx types.Tx, privAccounts []*account.PrivAccount) (*ResponseSignTx, error) { // more checks? for i, privAccount := range privAccounts { @@ -40,5 +40,5 @@ func SignTx(tx types.Tx, privAccounts []*account.PrivAccount) (types.Tx, error) rebondTx := tx.(*types.RebondTx) rebondTx.Signature = privAccounts[0].Sign(rebondTx).(account.SignatureEd25519) } - return tx, nil + return &ResponseSignTx{tx}, nil } diff --git a/rpc/core/validators.go b/rpc/core/validators.go index b1892f69b..5d156156d 100644 --- a/rpc/core/validators.go +++ b/rpc/core/validators.go @@ -6,7 +6,7 @@ import ( //----------------------------------------------------------------------------- -func ListValidators() (uint, []*sm.Validator, []*sm.Validator) { +func ListValidators() (*ResponseListValidators, error) { var blockHeight uint var bondedValidators []*sm.Validator var unbondingValidators []*sm.Validator @@ -22,5 +22,5 @@ func ListValidators() (uint, []*sm.Validator, []*sm.Validator) { return false }) - return blockHeight, bondedValidators, unbondingValidators + return &ResponseListValidators{blockHeight, bondedValidators, unbondingValidators}, nil } diff --git a/rpc/http_handlers.go b/rpc/http_handlers.go index 6cb499b1d..225561360 100644 --- a/rpc/http_handlers.go +++ b/rpc/http_handlers.go @@ -16,16 +16,16 @@ import ( // (func, responseStruct, argNames) // XXX: response structs are allocated once and reused - will this cause an issue eg. if a field ever not overwritten? var funcMap = map[string]*FuncWrapper{ - "status": funcWrap(core.Status, &ResponseStatus{}, []string{}), - "net_info": funcWrap(core.NetInfo, &ResponseNetInfo{}, []string{}), - "blockchain": funcWrap(core.BlockchainInfo, &ResponseBlockchainInfo{}, []string{"min_height", "max_height"}), - "get_block": funcWrap(core.GetBlock, &ResponseGetBlock{}, []string{"height"}), - "get_account": funcWrap(core.GetAccount, &ResponseGetAccount{}, []string{"address"}), - "list_validators": funcWrap(core.ListValidators, &ResponseListValidators{}, []string{}), - "broadcast_tx": funcWrap(core.BroadcastTx, &ResponseBroadcastTx{}, []string{"tx"}), - "list_accounts": funcWrap(core.ListAccounts, &ResponseListAccounts{}, []string{}), - "unsafe/gen_priv_account": funcWrap(core.GenPrivAccount, &ResponseGenPrivAccount{}, []string{}), - "unsafe/sign_tx": funcWrap(core.SignTx, &ResponseSignTx{}, []string{"tx", "privAccounts"}), + "status": funcWrap(core.Status, []string{}), + "net_info": funcWrap(core.NetInfo, []string{}), + "blockchain": funcWrap(core.BlockchainInfo, []string{"min_height", "max_height"}), + "get_block": funcWrap(core.GetBlock, []string{"height"}), + "get_account": funcWrap(core.GetAccount, []string{"address"}), + "list_validators": funcWrap(core.ListValidators, []string{}), + "broadcast_tx": funcWrap(core.BroadcastTx, []string{"tx"}), + "list_accounts": funcWrap(core.ListAccounts, []string{}), + "unsafe/gen_priv_account": funcWrap(core.GenPrivAccount, []string{}), + "unsafe/sign_tx": funcWrap(core.SignTx, []string{"tx", "privAccounts"}), } // holds all type information for each function @@ -34,16 +34,14 @@ type FuncWrapper struct { args []reflect.Type // type of each function arg returns []reflect.Type // type of each return arg argNames []string // name of each argument - response reflect.Value // response struct (to be filled with "returns") } -func funcWrap(f interface{}, response interface{}, args []string) *FuncWrapper { +func funcWrap(f interface{}, args []string) *FuncWrapper { return &FuncWrapper{ f: reflect.ValueOf(f), args: funcArgTypes(f), returns: funcReturnTypes(f), argNames: args, - response: reflect.ValueOf(response), } } @@ -170,6 +168,16 @@ func paramsToValues(funcInfo *FuncWrapper, params []string) ([]reflect.Value, er return values, nil } +// returns is Response struct and error. If error is not nil, return it +func returnsToResponse(funcInfo *FuncWrapper, returns []reflect.Value) (interface{}, error) { + errV := returns[1] + if errV.Interface() != nil { + return nil, fmt.Errorf("%v", errV.Interface()) + } + return returns[0].Interface(), nil +} + +/* // convert a list of values to a populated struct with the correct types func returnsToResponse(funcInfo *FuncWrapper, returns []reflect.Value) (interface{}, error) { returnTypes := funcInfo.returns @@ -190,7 +198,7 @@ func returnsToResponse(funcInfo *FuncWrapper, returns []reflect.Value) (interfac } return v.Interface(), nil -} +}*/ // jsonrpc calls grab the given method's function info and runs reflect.Call func JsonRpcHandler(w http.ResponseWriter, r *http.Request) { diff --git a/rpc/test/http_rpc_test.go b/rpc/test/http_rpc_test.go index a6a5fb2f2..3021584c3 100644 --- a/rpc/test/http_rpc_test.go +++ b/rpc/test/http_rpc_test.go @@ -8,7 +8,7 @@ import ( "github.com/tendermint/tendermint/binary" "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/merkle" - "github.com/tendermint/tendermint/rpc" + "github.com/tendermint/tendermint/rpc/core" "github.com/tendermint/tendermint/types" "io/ioutil" "net/http" @@ -28,7 +28,7 @@ func TestHTTPStatus(t *testing.T) { } var status struct { Status string - Data rpc.ResponseStatus + Data core.ResponseStatus Error string } err = json.Unmarshal(body, &status) @@ -56,7 +56,7 @@ func TestHTTPGenPriv(t *testing.T) { } var status struct { Status string - Data rpc.ResponseGenPrivAccount + Data core.ResponseGenPrivAccount Error string } binary.ReadJSON(&status, body, &err) @@ -118,7 +118,7 @@ func TestHTTPBroadcastTx(t *testing.T) { var status struct { Status string - Data rpc.ResponseBroadcastTx + Data core.ResponseBroadcastTx Error string } requestResponse(t, "broadcast_tx", url.Values{"tx": {string(b)}}, &status) diff --git a/rpc/test/json_rpc_test.go b/rpc/test/json_rpc_test.go index d40f579f8..62f9c60bb 100644 --- a/rpc/test/json_rpc_test.go +++ b/rpc/test/json_rpc_test.go @@ -9,6 +9,7 @@ import ( "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/merkle" "github.com/tendermint/tendermint/rpc" + "github.com/tendermint/tendermint/rpc/core" "github.com/tendermint/tendermint/types" "io/ioutil" "net/http" @@ -39,7 +40,7 @@ func TestJSONStatus(t *testing.T) { } status := new(struct { Status string - Data rpc.ResponseStatus + Data core.ResponseStatus Error string }) err = json.Unmarshal(body, status) @@ -77,7 +78,7 @@ func TestJSONGenPriv(t *testing.T) { } var status struct { Status string - Data rpc.ResponseGenPrivAccount + Data core.ResponseGenPrivAccount Error string } binary.ReadJSON(&status, body, &err) @@ -139,7 +140,7 @@ func TestJSONBroadcastTx(t *testing.T) { var status struct { Status string - Data rpc.ResponseBroadcastTx + Data core.ResponseBroadcastTx Error string } requestResponse(t, "broadcast_tx", url.Values{"tx": {string(b)}}, &status) diff --git a/rpc/test/test.go b/rpc/test/test.go index 3057a8bf6..45a5f412a 100644 --- a/rpc/test/test.go +++ b/rpc/test/test.go @@ -12,6 +12,7 @@ import ( "github.com/tendermint/tendermint/logger" "github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/rpc" + "github.com/tendermint/tendermint/rpc/core" "github.com/tendermint/tendermint/types" "io/ioutil" "net/http" @@ -101,7 +102,7 @@ func getAccount(t *testing.T, typ string, addr []byte) *account.Account { } var status struct { Status string - Data rpc.ResponseGetAccount + Data core.ResponseGetAccount Error string } fmt.Println(string(body)) @@ -182,7 +183,7 @@ func signTx(t *testing.T, typ string, fromAddr, toAddr []byte, key [64]byte, amt var status struct { Status string - Data rpc.ResponseSignTx + Data core.ResponseSignTx Error string } requestResponse(t, "unsafe/sign_tx", url.Values{"tx": {string(b)}, "privAccounts": {string(w.Bytes())}}, &status)