rpc: return (*Response, error) for all functions

This commit is contained in:
Ethan Buchman 2015-03-28 23:10:05 -07:00
parent d30fc2fa43
commit 731de7a6aa
11 changed files with 58 additions and 49 deletions

View File

@ -6,20 +6,20 @@ import (
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func GenPrivAccount() *account.PrivAccount { func GenPrivAccount() (*ResponseGenPrivAccount, error) {
return account.GenPrivAccount() return &ResponseGenPrivAccount{account.GenPrivAccount()}, nil
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func GetAccount(address []byte) *account.Account { func GetAccount(address []byte) (*ResponseGetAccount, error) {
state := consensusState.GetState() 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 blockHeight uint
var accounts []*account.Account var accounts []*account.Account
state := consensusState.GetState() state := consensusState.GetState()
@ -28,5 +28,5 @@ func ListAccounts() (uint, []*account.Account) {
accounts = append(accounts, value.(*account.Account)) accounts = append(accounts, value.(*account.Account))
return false return false
}) })
return blockHeight, accounts return &ResponseListAccounts{blockHeight, accounts}, nil
} }

View File

@ -8,7 +8,7 @@ import (
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func BlockchainInfo(minHeight, maxHeight uint) (uint, []*types.BlockMeta) { func BlockchainInfo(minHeight, maxHeight uint) (*ResponseBlockchainInfo, error) {
if maxHeight == 0 { if maxHeight == 0 {
maxHeight = blockStore.Height() maxHeight = blockStore.Height()
} else { } else {
@ -25,20 +25,20 @@ func BlockchainInfo(minHeight, maxHeight uint) (uint, []*types.BlockMeta) {
blockMetas = append(blockMetas, 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 { 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() { 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) blockMeta := blockStore.LoadBlockMeta(height)
block := blockStore.LoadBlock(height) block := blockStore.LoadBlock(height)
return blockMeta, block, nil return &ResponseGetBlock{blockMeta, block}, nil
} }

View File

@ -18,10 +18,10 @@ type Receipt struct {
// pass pointer? // pass pointer?
// Note: tx must be signed // Note: tx must be signed
func BroadcastTx(tx types.Tx) (Receipt, error) { func BroadcastTx(tx types.Tx) (*ResponseBroadcastTx, error) {
err := mempoolReactor.BroadcastTx(tx) err := mempoolReactor.BroadcastTx(tx)
if err != nil { 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) 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)) contractAddr = state.NewContractAddress(callTx.Input.Address, uint64(callTx.Input.Sequence))
} }
} }
return Receipt{txHash, createsContract, contractAddr}, nil return &ResponseBroadcastTx{Receipt{txHash, createsContract, contractAddr}}, nil
} }
/* /*

View File

@ -9,7 +9,7 @@ import (
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func Status() ([]byte, string, []byte, uint, int64) { func Status() (*ResponseStatus, error) {
db := dbm.NewMemDB() db := dbm.NewMemDB()
genesisState := sm.MakeGenesisStateFromFile(db, config.App().GetString("GenesisFile")) genesisState := sm.MakeGenesisStateFromFile(db, config.App().GetString("GenesisFile"))
genesisHash := genesisState.Hash() genesisHash := genesisState.Hash()
@ -25,15 +25,15 @@ func Status() ([]byte, string, []byte, uint, int64) {
latestBlockTime = latestBlockMeta.Header.Time.UnixNano() 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() o, i, _ := p2pSwitch.NumPeers()
numPeers := o + i numPeers := o + i
listening := p2pSwitch.IsListening() listening := p2pSwitch.IsListening()
network := config.App().GetString("Network") network := config.App().GetString("Network")
return numPeers, listening, network return &ResponseNetInfo{numPeers, listening, network}, nil
} }

View File

@ -1,8 +1,7 @@
package rpc package core
import ( import (
"github.com/tendermint/tendermint/account" "github.com/tendermint/tendermint/account"
"github.com/tendermint/tendermint/rpc/core"
sm "github.com/tendermint/tendermint/state" sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types" "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=... // curl -H 'content-type: text/plain;' http://127.0.0.1:8888/submit_tx?tx=...
type ResponseBroadcastTx struct { type ResponseBroadcastTx struct {
Receipt core.Receipt Receipt Receipt
} }
type ResponseStatus struct { type ResponseStatus struct {

View File

@ -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? // more checks?
for i, privAccount := range privAccounts { 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 := tx.(*types.RebondTx)
rebondTx.Signature = privAccounts[0].Sign(rebondTx).(account.SignatureEd25519) rebondTx.Signature = privAccounts[0].Sign(rebondTx).(account.SignatureEd25519)
} }
return tx, nil return &ResponseSignTx{tx}, nil
} }

View File

@ -6,7 +6,7 @@ import (
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func ListValidators() (uint, []*sm.Validator, []*sm.Validator) { func ListValidators() (*ResponseListValidators, error) {
var blockHeight uint var blockHeight uint
var bondedValidators []*sm.Validator var bondedValidators []*sm.Validator
var unbondingValidators []*sm.Validator var unbondingValidators []*sm.Validator
@ -22,5 +22,5 @@ func ListValidators() (uint, []*sm.Validator, []*sm.Validator) {
return false return false
}) })
return blockHeight, bondedValidators, unbondingValidators return &ResponseListValidators{blockHeight, bondedValidators, unbondingValidators}, nil
} }

View File

@ -16,16 +16,16 @@ import (
// (func, responseStruct, argNames) // (func, responseStruct, argNames)
// XXX: response structs are allocated once and reused - will this cause an issue eg. if a field ever not overwritten? // 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{ var funcMap = map[string]*FuncWrapper{
"status": funcWrap(core.Status, &ResponseStatus{}, []string{}), "status": funcWrap(core.Status, []string{}),
"net_info": funcWrap(core.NetInfo, &ResponseNetInfo{}, []string{}), "net_info": funcWrap(core.NetInfo, []string{}),
"blockchain": funcWrap(core.BlockchainInfo, &ResponseBlockchainInfo{}, []string{"min_height", "max_height"}), "blockchain": funcWrap(core.BlockchainInfo, []string{"min_height", "max_height"}),
"get_block": funcWrap(core.GetBlock, &ResponseGetBlock{}, []string{"height"}), "get_block": funcWrap(core.GetBlock, []string{"height"}),
"get_account": funcWrap(core.GetAccount, &ResponseGetAccount{}, []string{"address"}), "get_account": funcWrap(core.GetAccount, []string{"address"}),
"list_validators": funcWrap(core.ListValidators, &ResponseListValidators{}, []string{}), "list_validators": funcWrap(core.ListValidators, []string{}),
"broadcast_tx": funcWrap(core.BroadcastTx, &ResponseBroadcastTx{}, []string{"tx"}), "broadcast_tx": funcWrap(core.BroadcastTx, []string{"tx"}),
"list_accounts": funcWrap(core.ListAccounts, &ResponseListAccounts{}, []string{}), "list_accounts": funcWrap(core.ListAccounts, []string{}),
"unsafe/gen_priv_account": funcWrap(core.GenPrivAccount, &ResponseGenPrivAccount{}, []string{}), "unsafe/gen_priv_account": funcWrap(core.GenPrivAccount, []string{}),
"unsafe/sign_tx": funcWrap(core.SignTx, &ResponseSignTx{}, []string{"tx", "privAccounts"}), "unsafe/sign_tx": funcWrap(core.SignTx, []string{"tx", "privAccounts"}),
} }
// holds all type information for each function // holds all type information for each function
@ -34,16 +34,14 @@ type FuncWrapper struct {
args []reflect.Type // type of each function arg args []reflect.Type // type of each function arg
returns []reflect.Type // type of each return arg returns []reflect.Type // type of each return arg
argNames []string // name of each argument 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{ return &FuncWrapper{
f: reflect.ValueOf(f), f: reflect.ValueOf(f),
args: funcArgTypes(f), args: funcArgTypes(f),
returns: funcReturnTypes(f), returns: funcReturnTypes(f),
argNames: args, argNames: args,
response: reflect.ValueOf(response),
} }
} }
@ -170,6 +168,16 @@ func paramsToValues(funcInfo *FuncWrapper, params []string) ([]reflect.Value, er
return values, nil 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 // convert a list of values to a populated struct with the correct types
func returnsToResponse(funcInfo *FuncWrapper, returns []reflect.Value) (interface{}, error) { func returnsToResponse(funcInfo *FuncWrapper, returns []reflect.Value) (interface{}, error) {
returnTypes := funcInfo.returns returnTypes := funcInfo.returns
@ -190,7 +198,7 @@ func returnsToResponse(funcInfo *FuncWrapper, returns []reflect.Value) (interfac
} }
return v.Interface(), nil return v.Interface(), nil
} }*/
// jsonrpc calls grab the given method's function info and runs reflect.Call // jsonrpc calls grab the given method's function info and runs reflect.Call
func JsonRpcHandler(w http.ResponseWriter, r *http.Request) { func JsonRpcHandler(w http.ResponseWriter, r *http.Request) {

View File

@ -8,7 +8,7 @@ import (
"github.com/tendermint/tendermint/binary" "github.com/tendermint/tendermint/binary"
"github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/merkle" "github.com/tendermint/tendermint/merkle"
"github.com/tendermint/tendermint/rpc" "github.com/tendermint/tendermint/rpc/core"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -28,7 +28,7 @@ func TestHTTPStatus(t *testing.T) {
} }
var status struct { var status struct {
Status string Status string
Data rpc.ResponseStatus Data core.ResponseStatus
Error string Error string
} }
err = json.Unmarshal(body, &status) err = json.Unmarshal(body, &status)
@ -56,7 +56,7 @@ func TestHTTPGenPriv(t *testing.T) {
} }
var status struct { var status struct {
Status string Status string
Data rpc.ResponseGenPrivAccount Data core.ResponseGenPrivAccount
Error string Error string
} }
binary.ReadJSON(&status, body, &err) binary.ReadJSON(&status, body, &err)
@ -118,7 +118,7 @@ func TestHTTPBroadcastTx(t *testing.T) {
var status struct { var status struct {
Status string Status string
Data rpc.ResponseBroadcastTx Data core.ResponseBroadcastTx
Error string Error string
} }
requestResponse(t, "broadcast_tx", url.Values{"tx": {string(b)}}, &status) requestResponse(t, "broadcast_tx", url.Values{"tx": {string(b)}}, &status)

View File

@ -9,6 +9,7 @@ import (
"github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/merkle" "github.com/tendermint/tendermint/merkle"
"github.com/tendermint/tendermint/rpc" "github.com/tendermint/tendermint/rpc"
"github.com/tendermint/tendermint/rpc/core"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -39,7 +40,7 @@ func TestJSONStatus(t *testing.T) {
} }
status := new(struct { status := new(struct {
Status string Status string
Data rpc.ResponseStatus Data core.ResponseStatus
Error string Error string
}) })
err = json.Unmarshal(body, status) err = json.Unmarshal(body, status)
@ -77,7 +78,7 @@ func TestJSONGenPriv(t *testing.T) {
} }
var status struct { var status struct {
Status string Status string
Data rpc.ResponseGenPrivAccount Data core.ResponseGenPrivAccount
Error string Error string
} }
binary.ReadJSON(&status, body, &err) binary.ReadJSON(&status, body, &err)
@ -139,7 +140,7 @@ func TestJSONBroadcastTx(t *testing.T) {
var status struct { var status struct {
Status string Status string
Data rpc.ResponseBroadcastTx Data core.ResponseBroadcastTx
Error string Error string
} }
requestResponse(t, "broadcast_tx", url.Values{"tx": {string(b)}}, &status) requestResponse(t, "broadcast_tx", url.Values{"tx": {string(b)}}, &status)

View File

@ -12,6 +12,7 @@ import (
"github.com/tendermint/tendermint/logger" "github.com/tendermint/tendermint/logger"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/rpc" "github.com/tendermint/tendermint/rpc"
"github.com/tendermint/tendermint/rpc/core"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -101,7 +102,7 @@ func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
} }
var status struct { var status struct {
Status string Status string
Data rpc.ResponseGetAccount Data core.ResponseGetAccount
Error string Error string
} }
fmt.Println(string(body)) 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 { var status struct {
Status string Status string
Data rpc.ResponseSignTx Data core.ResponseSignTx
Error string Error string
} }
requestResponse(t, "unsafe/sign_tx", url.Values{"tx": {string(b)}, "privAccounts": {string(w.Bytes())}}, &status) requestResponse(t, "unsafe/sign_tx", url.Values{"tx": {string(b)}, "privAccounts": {string(w.Bytes())}}, &status)