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 {
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
}

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 {
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
}

View File

@ -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
}
/*

View File

@ -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
}

View File

@ -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 {

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?
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
}

View File

@ -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
}

View File

@ -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) {

View File

@ -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)

View File

@ -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)

View File

@ -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)