From 7f8b75e1ee6bbd838d64923dab1a7b271cc727aa Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Tue, 11 Jan 2022 06:37:38 -0800 Subject: [PATCH] rpc: replace anonymous arguments with structured types (#7552) Instead of using anonymous maps, define tagged struct types for JSON argument encoding. This allows us to have the encoding rules we want without tmjson. This commit handles the "easy" cases. BroadcastEvidence is omitted here, because it depends on the interface encoding rules from tmjson. I will address that in a forthcoming change. --- rpc/client/http/http.go | 153 +++++++++++++------------------------ rpc/client/http/request.go | 59 ++++++++++++++ 2 files changed, 110 insertions(+), 102 deletions(-) create mode 100644 rpc/client/http/request.go diff --git a/rpc/client/http/http.go b/rpc/client/http/http.go index de4269179..7dd6abb76 100644 --- a/rpc/client/http/http.go +++ b/rpc/client/http/http.go @@ -203,7 +203,7 @@ func (b *BatchHTTP) Count() int { func (c *baseRPCClient) Status(ctx context.Context) (*coretypes.ResultStatus, error) { result := new(coretypes.ResultStatus) - if err := c.caller.Call(ctx, "status", map[string]interface{}{}, result); err != nil { + if err := c.caller.Call(ctx, "status", nil, result); err != nil { return nil, err } return result, nil @@ -211,7 +211,7 @@ func (c *baseRPCClient) Status(ctx context.Context) (*coretypes.ResultStatus, er func (c *baseRPCClient) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { result := new(coretypes.ResultABCIInfo) - if err := c.caller.Call(ctx, "abci_info", map[string]interface{}{}, result); err != nil { + if err := c.caller.Call(ctx, "abci_info", nil, result); err != nil { return nil, err } return result, nil @@ -231,9 +231,12 @@ func (c *baseRPCClient) ABCIQueryWithOptions( data bytes.HexBytes, opts rpcclient.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { result := new(coretypes.ResultABCIQuery) - if err := c.caller.Call(ctx, "abci_query", - map[string]interface{}{"path": path, "data": data, "height": opts.Height, "prove": opts.Prove}, - result); err != nil { + if err := c.caller.Call(ctx, "abci_query", abciQueryArgs{ + Path: path, + Data: data, + Height: opts.Height, + Prove: opts.Prove, + }, result); err != nil { return nil, err } return result, nil @@ -244,7 +247,7 @@ func (c *baseRPCClient) BroadcastTxCommit( tx types.Tx, ) (*coretypes.ResultBroadcastTxCommit, error) { result := new(coretypes.ResultBroadcastTxCommit) - if err := c.caller.Call(ctx, "broadcast_tx_commit", map[string]interface{}{"tx": tx}, result); err != nil { + if err := c.caller.Call(ctx, "broadcast_tx_commit", txArgs{Tx: tx}, result); err != nil { return nil, err } return result, nil @@ -270,7 +273,7 @@ func (c *baseRPCClient) broadcastTX( tx types.Tx, ) (*coretypes.ResultBroadcastTx, error) { result := new(coretypes.ResultBroadcastTx) - if err := c.caller.Call(ctx, route, map[string]interface{}{"tx": tx}, result); err != nil { + if err := c.caller.Call(ctx, route, txArgs{Tx: tx}, result); err != nil { return nil, err } return result, nil @@ -281,11 +284,8 @@ func (c *baseRPCClient) UnconfirmedTxs( limit *int, ) (*coretypes.ResultUnconfirmedTxs, error) { result := new(coretypes.ResultUnconfirmedTxs) - params := make(map[string]interface{}) - if limit != nil { - params["limit"] = limit - } - if err := c.caller.Call(ctx, "unconfirmed_txs", params, result); err != nil { + + if err := c.caller.Call(ctx, "unconfirmed_txs", unconfirmedArgs{Limit: limit}, result); err != nil { return nil, err } return result, nil @@ -293,7 +293,7 @@ func (c *baseRPCClient) UnconfirmedTxs( func (c *baseRPCClient) NumUnconfirmedTxs(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error) { result := new(coretypes.ResultUnconfirmedTxs) - if err := c.caller.Call(ctx, "num_unconfirmed_txs", map[string]interface{}{}, result); err != nil { + if err := c.caller.Call(ctx, "num_unconfirmed_txs", nil, result); err != nil { return nil, err } return result, nil @@ -301,14 +301,14 @@ func (c *baseRPCClient) NumUnconfirmedTxs(ctx context.Context) (*coretypes.Resul func (c *baseRPCClient) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) { result := new(coretypes.ResultCheckTx) - if err := c.caller.Call(ctx, "check_tx", map[string]interface{}{"tx": tx}, result); err != nil { + if err := c.caller.Call(ctx, "check_tx", txArgs{Tx: tx}, result); err != nil { return nil, err } return result, nil } func (c *baseRPCClient) RemoveTx(ctx context.Context, txKey types.TxKey) error { - if err := c.caller.Call(ctx, "remove_tx", map[string]interface{}{"tx_key": txKey}, nil); err != nil { + if err := c.caller.Call(ctx, "remove_tx", txKeyArgs{TxKey: txKey[:]}, nil); err != nil { return err } return nil @@ -316,7 +316,7 @@ func (c *baseRPCClient) RemoveTx(ctx context.Context, txKey types.TxKey) error { func (c *baseRPCClient) NetInfo(ctx context.Context) (*coretypes.ResultNetInfo, error) { result := new(coretypes.ResultNetInfo) - if err := c.caller.Call(ctx, "net_info", map[string]interface{}{}, result); err != nil { + if err := c.caller.Call(ctx, "net_info", nil, result); err != nil { return nil, err } return result, nil @@ -324,7 +324,7 @@ func (c *baseRPCClient) NetInfo(ctx context.Context) (*coretypes.ResultNetInfo, func (c *baseRPCClient) DumpConsensusState(ctx context.Context) (*coretypes.ResultDumpConsensusState, error) { result := new(coretypes.ResultDumpConsensusState) - if err := c.caller.Call(ctx, "dump_consensus_state", map[string]interface{}{}, result); err != nil { + if err := c.caller.Call(ctx, "dump_consensus_state", nil, result); err != nil { return nil, err } return result, nil @@ -332,7 +332,7 @@ func (c *baseRPCClient) DumpConsensusState(ctx context.Context) (*coretypes.Resu func (c *baseRPCClient) ConsensusState(ctx context.Context) (*coretypes.ResultConsensusState, error) { result := new(coretypes.ResultConsensusState) - if err := c.caller.Call(ctx, "consensus_state", map[string]interface{}{}, result); err != nil { + if err := c.caller.Call(ctx, "consensus_state", nil, result); err != nil { return nil, err } return result, nil @@ -343,11 +343,7 @@ func (c *baseRPCClient) ConsensusParams( height *int64, ) (*coretypes.ResultConsensusParams, error) { result := new(coretypes.ResultConsensusParams) - params := make(map[string]interface{}) - if height != nil { - params["height"] = height - } - if err := c.caller.Call(ctx, "consensus_params", params, result); err != nil { + if err := c.caller.Call(ctx, "consensus_params", heightArgs{Height: height}, result); err != nil { return nil, err } return result, nil @@ -355,7 +351,7 @@ func (c *baseRPCClient) ConsensusParams( func (c *baseRPCClient) Health(ctx context.Context) (*coretypes.ResultHealth, error) { result := new(coretypes.ResultHealth) - if err := c.caller.Call(ctx, "health", map[string]interface{}{}, result); err != nil { + if err := c.caller.Call(ctx, "health", nil, result); err != nil { return nil, err } return result, nil @@ -367,9 +363,10 @@ func (c *baseRPCClient) BlockchainInfo( maxHeight int64, ) (*coretypes.ResultBlockchainInfo, error) { result := new(coretypes.ResultBlockchainInfo) - if err := c.caller.Call(ctx, "blockchain", - map[string]interface{}{"minHeight": minHeight, "maxHeight": maxHeight}, - result); err != nil { + if err := c.caller.Call(ctx, "blockchain", blockchainInfoArgs{ + MinHeight: minHeight, + MaxHeight: maxHeight, + }, result); err != nil { return nil, err } return result, nil @@ -377,7 +374,7 @@ func (c *baseRPCClient) BlockchainInfo( func (c *baseRPCClient) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) { result := new(coretypes.ResultGenesis) - if err := c.caller.Call(ctx, "genesis", map[string]interface{}{}, result); err != nil { + if err := c.caller.Call(ctx, "genesis", nil, result); err != nil { return nil, err } return result, nil @@ -385,7 +382,7 @@ func (c *baseRPCClient) Genesis(ctx context.Context) (*coretypes.ResultGenesis, func (c *baseRPCClient) GenesisChunked(ctx context.Context, id uint) (*coretypes.ResultGenesisChunk, error) { result := new(coretypes.ResultGenesisChunk) - if err := c.caller.Call(ctx, "genesis_chunked", map[string]interface{}{"chunk": id}, result); err != nil { + if err := c.caller.Call(ctx, "genesis_chunked", genesisChunkArgs{Chunk: id}, result); err != nil { return nil, err } return result, nil @@ -393,11 +390,7 @@ func (c *baseRPCClient) GenesisChunked(ctx context.Context, id uint) (*coretypes func (c *baseRPCClient) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { result := new(coretypes.ResultBlock) - params := make(map[string]interface{}) - if height != nil { - params["height"] = height - } - if err := c.caller.Call(ctx, "block", params, result); err != nil { + if err := c.caller.Call(ctx, "block", heightArgs{Height: height}, result); err != nil { return nil, err } return result, nil @@ -405,10 +398,7 @@ func (c *baseRPCClient) Block(ctx context.Context, height *int64) (*coretypes.Re func (c *baseRPCClient) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) { result := new(coretypes.ResultBlock) - params := map[string]interface{}{ - "hash": hash, - } - if err := c.caller.Call(ctx, "block_by_hash", params, result); err != nil { + if err := c.caller.Call(ctx, "block_by_hash", hashArgs{Hash: hash}, result); err != nil { return nil, err } return result, nil @@ -419,11 +409,7 @@ func (c *baseRPCClient) BlockResults( height *int64, ) (*coretypes.ResultBlockResults, error) { result := new(coretypes.ResultBlockResults) - params := make(map[string]interface{}) - if height != nil { - params["height"] = height - } - if err := c.caller.Call(ctx, "block_results", params, result); err != nil { + if err := c.caller.Call(ctx, "block_results", heightArgs{Height: height}, result); err != nil { return nil, err } return result, nil @@ -431,11 +417,7 @@ func (c *baseRPCClient) BlockResults( func (c *baseRPCClient) Header(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) { result := new(coretypes.ResultHeader) - params := make(map[string]interface{}) - if height != nil { - params["height"] = height - } - if err := c.caller.Call(ctx, "header", params, result); err != nil { + if err := c.caller.Call(ctx, "header", heightArgs{Height: height}, result); err != nil { return nil, err } return result, nil @@ -443,10 +425,7 @@ func (c *baseRPCClient) Header(ctx context.Context, height *int64) (*coretypes.R func (c *baseRPCClient) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) { result := new(coretypes.ResultHeader) - params := map[string]interface{}{ - "hash": hash, - } - if err := c.caller.Call(ctx, "header_by_hash", params, result); err != nil { + if err := c.caller.Call(ctx, "header_by_hash", hashArgs{Hash: hash}, result); err != nil { return nil, err } return result, nil @@ -454,11 +433,7 @@ func (c *baseRPCClient) HeaderByHash(ctx context.Context, hash bytes.HexBytes) ( func (c *baseRPCClient) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { result := new(coretypes.ResultCommit) - params := make(map[string]interface{}) - if height != nil { - params["height"] = height - } - if err := c.caller.Call(ctx, "commit", params, result); err != nil { + if err := c.caller.Call(ctx, "commit", heightArgs{Height: height}, result); err != nil { return nil, err } return result, nil @@ -466,11 +441,7 @@ func (c *baseRPCClient) Commit(ctx context.Context, height *int64) (*coretypes.R func (c *baseRPCClient) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) { result := new(coretypes.ResultTx) - params := map[string]interface{}{ - "hash": hash, - "prove": prove, - } - if err := c.caller.Call(ctx, "tx", params, result); err != nil { + if err := c.caller.Call(ctx, "tx", hashArgs{Hash: hash, Prove: prove}, result); err != nil { return nil, err } return result, nil @@ -484,22 +455,14 @@ func (c *baseRPCClient) TxSearch( perPage *int, orderBy string, ) (*coretypes.ResultTxSearch, error) { - result := new(coretypes.ResultTxSearch) - params := map[string]interface{}{ - "query": query, - "prove": prove, - "order_by": orderBy, - } - - if page != nil { - params["page"] = page - } - if perPage != nil { - params["per_page"] = perPage - } - - if err := c.caller.Call(ctx, "tx_search", params, result); err != nil { + if err := c.caller.Call(ctx, "tx_search", searchArgs{ + Query: query, + Prove: prove, + OrderBy: orderBy, + Page: page, + PerPage: perPage, + }, result); err != nil { return nil, err } @@ -512,21 +475,13 @@ func (c *baseRPCClient) BlockSearch( page, perPage *int, orderBy string, ) (*coretypes.ResultBlockSearch, error) { - result := new(coretypes.ResultBlockSearch) - params := map[string]interface{}{ - "query": query, - "order_by": orderBy, - } - - if page != nil { - params["page"] = page - } - if perPage != nil { - params["per_page"] = perPage - } - - if err := c.caller.Call(ctx, "block_search", params, result); err != nil { + if err := c.caller.Call(ctx, "block_search", searchArgs{ + Query: query, + OrderBy: orderBy, + Page: page, + PerPage: perPage, + }, result); err != nil { return nil, err } @@ -540,17 +495,11 @@ func (c *baseRPCClient) Validators( perPage *int, ) (*coretypes.ResultValidators, error) { result := new(coretypes.ResultValidators) - params := make(map[string]interface{}) - if page != nil { - params["page"] = page - } - if perPage != nil { - params["per_page"] = perPage - } - if height != nil { - params["height"] = height - } - if err := c.caller.Call(ctx, "validators", params, result); err != nil { + if err := c.caller.Call(ctx, "validators", validatorArgs{ + Height: height, + Page: page, + PerPage: perPage, + }, result); err != nil { return nil, err } return result, nil diff --git a/rpc/client/http/request.go b/rpc/client/http/request.go new file mode 100644 index 000000000..5d1d3db5b --- /dev/null +++ b/rpc/client/http/request.go @@ -0,0 +1,59 @@ +package http + +// The types in this file define the JSON encoding for RPC method parameters +// from the client to the server. + +import ( + "github.com/tendermint/tendermint/libs/bytes" +) + +type abciQueryArgs struct { + Path string `json:"path"` + Data bytes.HexBytes `json:"data"` + Height int64 `json:"height,string"` + Prove bool `json:"prove"` +} + +type txArgs struct { + Tx []byte `json:"tx"` +} + +type txKeyArgs struct { + TxKey []byte `json:"tx_key"` +} + +type unconfirmedArgs struct { + Limit *int `json:"limit,string,omitempty"` +} + +type heightArgs struct { + Height *int64 `json:"height,string,omitempty"` +} + +type hashArgs struct { + Hash bytes.HexBytes `json:"hash"` + Prove bool `json:"prove,omitempty"` +} + +type blockchainInfoArgs struct { + MinHeight int64 `json:"minHeight,string"` + MaxHeight int64 `json:"maxHeight,string"` +} + +type genesisChunkArgs struct { + Chunk uint `json:"chunk,string"` +} + +type searchArgs struct { + Query string `json:"query"` + Prove bool `json:"prove,omitempty"` + OrderBy string `json:"order_by,omitempty"` + Page *int `json:"page,string,omitempty"` + PerPage *int `json:"per_page,string,omitempty"` +} + +type validatorArgs struct { + Height *int64 `json:"height,string,omitempty"` + Page *int `json:"page,string,omitempty"` + PerPage *int `json:"per_page,string,omitempty"` +}