From fb59255095fd44bec2b2da7debefbbce4d6e1dc1 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 12 Jan 2016 18:04:06 -0500 Subject: [PATCH] use TendermintResult for rpctypes.Result --- node/node.go | 10 ++++ rpc/core/events.go | 4 +- rpc/core/routes.go | 112 ++++++++++++++++++++++++++++++++---- rpc/core/types/responses.go | 10 +++- rpc/test/client_test.go | 2 +- rpc/test/helpers.go | 4 +- 6 files changed, 124 insertions(+), 18 deletions(-) diff --git a/node/node.go b/node/node.go index 124a87732..2e072aec4 100644 --- a/node/node.go +++ b/node/node.go @@ -16,12 +16,14 @@ import ( "github.com/tendermint/go-p2p" "github.com/tendermint/go-rpc" "github.com/tendermint/go-rpc/server" + "github.com/tendermint/go-rpc/types" "github.com/tendermint/go-wire" bc "github.com/tendermint/tendermint/blockchain" "github.com/tendermint/tendermint/consensus" mempl "github.com/tendermint/tendermint/mempool" "github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/rpc/core" + ctypes "github.com/tendermint/tendermint/rpc/core/types" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" "github.com/tendermint/tmsp/example/golang" @@ -181,6 +183,14 @@ func (n *Node) StartRPC() (net.Listener, error) { listenAddr := config.GetString("rpc_laddr") + // register the result objects with wire + // so consumers of tendermint rpc will not have + // conflicts with their own rpc + wire.RegisterInterface( + struct{ rpctypes.Result }{}, + wire.ConcreteType{&ctypes.TendermintResult{}, 0x1}, + ) + mux := http.NewServeMux() wm := rpcserver.NewWebsocketManager(core.Routes, n.evsw) mux.HandleFunc("/websocket", wm.WebsocketHandler) diff --git a/rpc/core/events.go b/rpc/core/events.go index 7365377d2..c9164e093 100644 --- a/rpc/core/events.go +++ b/rpc/core/events.go @@ -11,7 +11,7 @@ func Subscribe(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.ResultSubscri wsCtx.GetEventSwitch().AddListenerForEvent(wsCtx.GetRemoteAddr(), event, func(msg events.EventData) { // NOTE: EventSwitch callbacks must be nonblocking // NOTE: RPCResponses of subscribed events have id suffix "#event" - wsCtx.TryWriteRPCResponse(rpctypes.NewRPCResponse(wsCtx.Request.ID+"#event", &ctypes.ResultEvent{event, msg}, "")) + wsCtx.TryWriteRPCResponse(rpctypes.NewRPCResponse(wsCtx.Request.ID+"#event", &ctypes.TendermintResult{&ctypes.ResultEvent{event, msg}}, "")) }) return &ctypes.ResultSubscribe{}, nil } @@ -21,7 +21,7 @@ func Unsubscribe(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.ResultUnsub wsCtx.GetEventSwitch().AddListenerForEvent(wsCtx.GetRemoteAddr(), event, func(msg events.EventData) { // NOTE: EventSwitch callbacks must be nonblocking // NOTE: RPCResponses of subscribed events have id suffix "#event" - wsCtx.TryWriteRPCResponse(rpctypes.NewRPCResponse(wsCtx.Request.ID+"#event", &ctypes.ResultEvent{event, msg}, "")) + wsCtx.TryWriteRPCResponse(rpctypes.NewRPCResponse(wsCtx.Request.ID+"#event", &ctypes.TendermintResult{&ctypes.ResultEvent{event, msg}}, "")) }) return &ctypes.ResultUnsubscribe{}, nil } diff --git a/rpc/core/routes.go b/rpc/core/routes.go index 765c03b27..185625d0d 100644 --- a/rpc/core/routes.go +++ b/rpc/core/routes.go @@ -2,20 +2,110 @@ package core import ( rpc "github.com/tendermint/go-rpc/server" + "github.com/tendermint/go-rpc/types" + ctypes "github.com/tendermint/tendermint/rpc/core/types" ) // TODO: eliminate redundancy between here and reading code from core/ var Routes = map[string]*rpc.RPCFunc{ - "subscribe": rpc.NewWSRPCFunc(Subscribe, []string{"event"}), - "unsubscribe": rpc.NewWSRPCFunc(Unsubscribe, []string{"event"}), - "status": rpc.NewRPCFunc(Status, []string{}), - "net_info": rpc.NewRPCFunc(NetInfo, []string{}), - "blockchain": rpc.NewRPCFunc(BlockchainInfo, []string{"minHeight", "maxHeight"}), - "genesis": rpc.NewRPCFunc(Genesis, []string{}), - "get_block": rpc.NewRPCFunc(GetBlock, []string{"height"}), - "list_validators": rpc.NewRPCFunc(ListValidators, []string{}), - "dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, []string{}), - "broadcast_tx": rpc.NewRPCFunc(BroadcastTx, []string{"tx"}), - "list_unconfirmed_txs": rpc.NewRPCFunc(ListUnconfirmedTxs, []string{}), + "subscribe": rpc.NewWSRPCFunc(SubscribeResult, "event"), + "unsubscribe": rpc.NewWSRPCFunc(UnsubscribeResult, "event"), + "status": rpc.NewRPCFunc(StatusResult, ""), + "net_info": rpc.NewRPCFunc(NetInfoResult, ""), + "blockchain": rpc.NewRPCFunc(BlockchainInfoResult, "minHeight,maxHeight"), + "genesis": rpc.NewRPCFunc(GenesisResult, ""), + "get_block": rpc.NewRPCFunc(GetBlockResult, "height"), + "list_validators": rpc.NewRPCFunc(ListValidatorsResult, ""), + "dump_consensus_state": rpc.NewRPCFunc(DumpConsensusStateResult, ""), + "broadcast_tx": rpc.NewRPCFunc(BroadcastTxResult, "tx"), + "list_unconfirmed_txs": rpc.NewRPCFunc(ListUnconfirmedTxsResult, ""), // subscribe/unsubscribe are reserved for websocket events. } + +func SubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.TendermintResult, error) { + if r, err := Subscribe(wsCtx, event); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func UnsubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.TendermintResult, error) { + if r, err := Unsubscribe(wsCtx, event); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func StatusResult() (*ctypes.TendermintResult, error) { + if r, err := Status(); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func NetInfoResult() (*ctypes.TendermintResult, error) { + if r, err := NetInfo(); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func BlockchainInfoResult(min, max int) (*ctypes.TendermintResult, error) { + if r, err := BlockchainInfo(min, max); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func GenesisResult() (*ctypes.TendermintResult, error) { + if r, err := Genesis(); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func GetBlockResult(height int) (*ctypes.TendermintResult, error) { + if r, err := GetBlock(height); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func ListValidatorsResult() (*ctypes.TendermintResult, error) { + if r, err := ListValidators(); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func DumpConsensusStateResult() (*ctypes.TendermintResult, error) { + if r, err := DumpConsensusState(); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func ListUnconfirmedTxsResult() (*ctypes.TendermintResult, error) { + if r, err := ListUnconfirmedTxs(); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} + +func BroadcastTxResult(tx []byte) (*ctypes.TendermintResult, error) { + if r, err := BroadcastTx(tx); err != nil { + return nil, err + } else { + return &ctypes.TendermintResult{r}, nil + } +} diff --git a/rpc/core/types/responses.go b/rpc/core/types/responses.go index ac6737cfa..dad02f10b 100644 --- a/rpc/core/types/responses.go +++ b/rpc/core/types/responses.go @@ -4,7 +4,6 @@ import ( "github.com/tendermint/go-crypto" "github.com/tendermint/go-events" "github.com/tendermint/go-p2p" - "github.com/tendermint/go-rpc/types" "github.com/tendermint/go-wire" "github.com/tendermint/tendermint/types" ) @@ -92,9 +91,16 @@ const ( ResultTypeEvent = byte(0x0C) ) +type TendermintResultInterface interface{} + +// NOTE: up to the application to register this as rpctypes.Result +type TendermintResult struct { + Result TendermintResultInterface +} + // for wire.readReflect var _ = wire.RegisterInterface( - struct{ rpctypes.Result }{}, + struct{ TendermintResultInterface }{}, wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis}, wire.ConcreteType{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo}, wire.ConcreteType{&ResultGetBlock{}, ResultTypeGetBlock}, diff --git a/rpc/test/client_test.go b/rpc/test/client_test.go index ff04ce271..00f8c2b0c 100644 --- a/rpc/test/client_test.go +++ b/rpc/test/client_test.go @@ -29,7 +29,7 @@ func TestJSONStatus(t *testing.T) { } func testStatus(t *testing.T, result interface{}) { - status := result.(*ctypes.ResultStatus) + status := result.(*ctypes.TendermintResult).Result.(*ctypes.ResultStatus) if status.NodeInfo.Network != chainID { t.Fatal(fmt.Errorf("ChainID mismatch: got %s expected %s", status.NodeInfo.Network, chainID)) diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index 98ff0d96a..09e6aa23b 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -137,7 +137,7 @@ func waitForEvent(t *testing.T, con *websocket.Conn, eventid string, dieOnTimeou errCh <- err break } - event, ok := response.Result.(*ctypes.ResultEvent) + event, ok := response.Result.(*ctypes.TendermintResult).Result.(*ctypes.ResultEvent) if ok && event.Event == eventid { goodCh <- p break @@ -191,7 +191,7 @@ func unmarshalResponseNewBlock(b []byte) (*types.Block, error) { if response.Error != "" { return nil, fmt.Errorf(response.Error) } - block := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataNewBlock).Block + block := response.Result.(*ctypes.TendermintResult).Result.(*ctypes.ResultEvent).Data.(types.EventDataNewBlock).Block return block, nil }