Browse Source

Merge pull request #526 from tendermint/feature/rpc-docs

RPC docs
pull/623/head
Ethan Buchman 7 years ago
committed by GitHub
parent
commit
f2349b1092
11 changed files with 846 additions and 20 deletions
  1. +15
    -0
      rpc/core/README.md
  2. +64
    -2
      rpc/core/abci.go
  3. +221
    -7
      rpc/core/blocks.go
  4. +59
    -1
      rpc/core/consensus.go
  5. +107
    -0
      rpc/core/doc.go
  6. +8
    -0
      rpc/core/doc_template.txt
  7. +54
    -0
      rpc/core/events.go
  8. +150
    -1
      rpc/core/mempool.go
  9. +64
    -7
      rpc/core/net.go
  10. +47
    -0
      rpc/core/status.go
  11. +57
    -2
      rpc/core/tx.go

+ 15
- 0
rpc/core/README.md View File

@ -0,0 +1,15 @@
# Tendermint RPC
## Generate markdown for [Slate](https://github.com/tendermint/slate)
We are using [Slate](https://github.com/tendermint/slate) to power our RPC
documentation. If you are changing a comment, make sure to copy the resulting
changes to the slate repo and make a PR
[there](https://github.com/tendermint/slate) as well. For generating markdown
use:
```shell
go get github.com/melekes/godoc2md
godoc2md -template rpc/core/doc_template.txt github.com/tendermint/tendermint/rpc/core | grep -v -e "pipe.go" -e "routes.go" -e "dev.go" | sed 's$/src/target$https://github.com/tendermint/tendermint/tree/master/rpc/core$'
```

+ 64
- 2
rpc/core/abci.go View File

@ -6,8 +6,45 @@ import (
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
//-----------------------------------------------------------------------------
// Query the application for some information.
//
// ```shell
// curl 'localhost:46657/abci_query?path=""&data="abcd"&prove=true'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// result, err := client.ABCIQuery("", "abcd", true)
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "response": {
// "log": "exists",
// "height": 0,
// "proof": "010114FED0DAD959F36091AD761C922ABA3CBF1D8349990101020103011406AA2262E2F448242DF2C2607C3CDC705313EE3B0001149D16177BC71E445476174622EA559715C293740C",
// "value": "61626364",
// "key": "61626364",
// "index": -1,
// "code": 0
// }
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
//
// ### Query Parameters
//
// | Parameter | Type | Default | Required | Description |
// |-----------+--------+---------+----------+---------------------------------------|
// | path | string | false | false | Path to the data ("/a/b/c") |
// | data | []byte | false | true | Data |
// | prove | bool | false | false | Include a proof of the data inclusion |
func ABCIQuery(path string, data data.Bytes, prove bool) (*ctypes.ResultABCIQuery, error) {
resQuery, err := proxyAppQuery.QuerySync(abci.RequestQuery{
Path: path,
@ -23,6 +60,31 @@ func ABCIQuery(path string, data data.Bytes, prove bool) (*ctypes.ResultABCIQuer
}, nil
}
// Get some info about the application.
//
// ```shell
// curl 'localhost:46657/abci_info'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// info, err := client.ABCIInfo()
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "response": {
// "data": "{\"size\":3}"
// }
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func ABCIInfo() (*ctypes.ResultABCIInfo, error) {
resInfo, err := proxyAppQuery.InfoSync()
if err != nil {


+ 221
- 7
rpc/core/blocks.go View File

@ -8,9 +8,59 @@ import (
. "github.com/tendermint/tmlibs/common"
)
//-----------------------------------------------------------------------------
// Returns at most 20 blocks
// Get block headers for minHeight <= height <= maxHeight.
//
// ```shell
// curl 'localhost:46657/blockchain?minHeight=10&maxHeight=10'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// info, err := client.BlockchainInfo(10, 10)
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "block_metas": [
// {
// "header": {
// "app_hash": "",
// "chain_id": "test-chain-6UTNIN",
// "height": 10,
// "time": "2017-05-29T15:05:53.877Z",
// "num_txs": 0,
// "last_block_id": {
// "parts": {
// "hash": "3C78F00658E06744A88F24FF97A0A5011139F34A",
// "total": 1
// },
// "hash": "F70588DAB36BDA5A953D548A16F7D48C6C2DFD78"
// },
// "last_commit_hash": "F31CC4282E50B3F2A58D763D233D76F26D26CABE",
// "data_hash": "",
// "validators_hash": "9365FC80F234C967BD233F5A3E2AB2F1E4B0E5AA"
// },
// "block_id": {
// "parts": {
// "hash": "277A4DBEF91483A18B85F2F5677ABF9694DFA40F",
// "total": 1
// },
// "hash": "96B1D2F2D201BA4BC383EB8224139DB1294944E5"
// }
// }
// ],
// "last_height": 5493
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
//
// <aside class="notice">Returns at most 20 items.</aside>
func BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResultBlockchainInfo, error) {
if maxHeight == 0 {
maxHeight = blockStore.Height()
@ -34,8 +84,105 @@ func BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResultBlockchainInfo, err
return &ctypes.ResultBlockchainInfo{blockStore.Height(), blockMetas}, nil
}
//-----------------------------------------------------------------------------
// Get block at a given height.
//
// ```shell
// curl 'localhost:46657/block?height=10'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// info, err := client.Block(10)
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "block": {
// "last_commit": {
// "precommits": [
// {
// "signature": {
// "data": "12C0D8893B8A38224488DC1DE6270DF76BB1A5E9DB1C68577706A6A97C6EC34FFD12339183D5CA8BC2F46148773823DE905B7F6F5862FD564038BB7AE03BF50D",
// "type": "ed25519"
// },
// "block_id": {
// "parts": {
// "hash": "3C78F00658E06744A88F24FF97A0A5011139F34A",
// "total": 1
// },
// "hash": "F70588DAB36BDA5A953D548A16F7D48C6C2DFD78"
// },
// "type": 2,
// "round": 0,
// "height": 9,
// "validator_index": 0,
// "validator_address": "E89A51D60F68385E09E716D353373B11F8FACD62"
// }
// ],
// "blockID": {
// "parts": {
// "hash": "3C78F00658E06744A88F24FF97A0A5011139F34A",
// "total": 1
// },
// "hash": "F70588DAB36BDA5A953D548A16F7D48C6C2DFD78"
// }
// },
// "data": {
// "txs": []
// },
// "header": {
// "app_hash": "",
// "chain_id": "test-chain-6UTNIN",
// "height": 10,
// "time": "2017-05-29T15:05:53.877Z",
// "num_txs": 0,
// "last_block_id": {
// "parts": {
// "hash": "3C78F00658E06744A88F24FF97A0A5011139F34A",
// "total": 1
// },
// "hash": "F70588DAB36BDA5A953D548A16F7D48C6C2DFD78"
// },
// "last_commit_hash": "F31CC4282E50B3F2A58D763D233D76F26D26CABE",
// "data_hash": "",
// "validators_hash": "9365FC80F234C967BD233F5A3E2AB2F1E4B0E5AA"
// }
// },
// "block_meta": {
// "header": {
// "app_hash": "",
// "chain_id": "test-chain-6UTNIN",
// "height": 10,
// "time": "2017-05-29T15:05:53.877Z",
// "num_txs": 0,
// "last_block_id": {
// "parts": {
// "hash": "3C78F00658E06744A88F24FF97A0A5011139F34A",
// "total": 1
// },
// "hash": "F70588DAB36BDA5A953D548A16F7D48C6C2DFD78"
// },
// "last_commit_hash": "F31CC4282E50B3F2A58D763D233D76F26D26CABE",
// "data_hash": "",
// "validators_hash": "9365FC80F234C967BD233F5A3E2AB2F1E4B0E5AA"
// },
// "block_id": {
// "parts": {
// "hash": "277A4DBEF91483A18B85F2F5677ABF9694DFA40F",
// "total": 1
// },
// "hash": "96B1D2F2D201BA4BC383EB8224139DB1294944E5"
// }
// }
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func Block(height int) (*ctypes.ResultBlock, error) {
if height == 0 {
return nil, fmt.Errorf("Height must be greater than 0")
@ -49,8 +196,75 @@ func Block(height int) (*ctypes.ResultBlock, error) {
return &ctypes.ResultBlock{blockMeta, block}, nil
}
//-----------------------------------------------------------------------------
// Get block commit at a given height.
//
// ```shell
// curl 'localhost:46657/commit?height=11'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// info, err := client.Commit(11)
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "canonical": true,
// "commit": {
// "precommits": [
// {
// "signature": {
// "data": "00970429FEC652E9E21D106A90AE8C5413759A7488775CEF4A3F44DC46C7F9D941070E4FBE9ED54DF247FA3983359A0C3A238D61DE55C75C9116D72ABC9CF50F",
// "type": "ed25519"
// },
// "block_id": {
// "parts": {
// "hash": "9E37CBF266BC044A779E09D81C456E653B89E006",
// "total": 1
// },
// "hash": "CC6E861E31CA4334E9888381B4A9137D1458AB6A"
// },
// "type": 2,
// "round": 0,
// "height": 11,
// "validator_index": 0,
// "validator_address": "E89A51D60F68385E09E716D353373B11F8FACD62"
// }
// ],
// "blockID": {
// "parts": {
// "hash": "9E37CBF266BC044A779E09D81C456E653B89E006",
// "total": 1
// },
// "hash": "CC6E861E31CA4334E9888381B4A9137D1458AB6A"
// }
// },
// "header": {
// "app_hash": "",
// "chain_id": "test-chain-6UTNIN",
// "height": 11,
// "time": "2017-05-29T15:05:54.893Z",
// "num_txs": 0,
// "last_block_id": {
// "parts": {
// "hash": "277A4DBEF91483A18B85F2F5677ABF9694DFA40F",
// "total": 1
// },
// "hash": "96B1D2F2D201BA4BC383EB8224139DB1294944E5"
// },
// "last_commit_hash": "3CE0C9727CE524BA9CB7C91E28F08E2B94001087",
// "data_hash": "",
// "validators_hash": "9365FC80F234C967BD233F5A3E2AB2F1E4B0E5AA"
// }
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func Commit(height int) (*ctypes.ResultCommit, error) {
if height == 0 {
return nil, fmt.Errorf("Height must be greater than 0")


+ 59
- 1
rpc/core/consensus.go View File

@ -1,17 +1,75 @@
package core
import (
"github.com/tendermint/go-wire"
wire "github.com/tendermint/go-wire"
cm "github.com/tendermint/tendermint/consensus"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
)
// Get current validators set along with a block height.
//
// ```shell
// curl 'localhost:46657/validators'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// state, err := client.Validators()
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "validators": [
// {
// "accum": 0,
// "voting_power": 10,
// "pub_key": {
// "data": "68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D",
// "type": "ed25519"
// },
// "address": "E89A51D60F68385E09E716D353373B11F8FACD62"
// }
// ],
// "block_height": 5241
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func Validators() (*ctypes.ResultValidators, error) {
blockHeight, validators := consensusState.GetValidators()
return &ctypes.ResultValidators{blockHeight, validators}, nil
}
// Dump consensus state.
//
// ```shell
// curl 'localhost:46657/dump_consensus_state'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// state, err := client.DumpConsensusState()
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "peer_round_states": [],
// "round_state": "RoundState{\n H:3537 R:0 S:RoundStepNewHeight\n StartTime: 2017-05-31 12:32:31.178653883 +0000 UTC\n CommitTime: 2017-05-31 12:32:30.178653883 +0000 UTC\n Validators: ValidatorSet{\n Proposer: Validator{E89A51D60F68385E09E716D353373B11F8FACD62 {PubKeyEd25519{68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D}} VP:10 A:0}\n Validators:\n Validator{E89A51D60F68385E09E716D353373B11F8FACD62 {PubKeyEd25519{68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D}} VP:10 A:0}\n }\n Proposal: <nil>\n ProposalBlock: nil-PartSet nil-Block\n LockedRound: 0\n LockedBlock: nil-PartSet nil-Block\n Votes: HeightVoteSet{H:3537 R:0~0\n VoteSet{H:3537 R:0 T:1 +2/3:<nil> BA{1:_} map[]}\n VoteSet{H:3537 R:0 T:2 +2/3:<nil> BA{1:_} map[]}\n }\n LastCommit: VoteSet{H:3536 R:0 T:2 +2/3:B7F988FBCDC68F9320E346EECAA76E32F6054654:1:673BE7C01F74 BA{1:X} map[]}\n LastValidators: ValidatorSet{\n Proposer: Validator{E89A51D60F68385E09E716D353373B11F8FACD62 {PubKeyEd25519{68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D}} VP:10 A:0}\n Validators:\n Validator{E89A51D60F68385E09E716D353373B11F8FACD62 {PubKeyEd25519{68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D}} VP:10 A:0}\n }\n}"
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
roundState := consensusState.GetRoundState()
peerRoundStates := []string{}


+ 107
- 0
rpc/core/doc.go View File

@ -0,0 +1,107 @@
/*
# Introduction
Tendermint supports the following RPC protocols:
* URI over HTTP
* JSONRPC over HTTP
* JSONRPC over websockets
Tendermint RPC is built using [our own RPC library](https://github.com/tendermint/tendermint/tree/master/rpc/lib). Documentation and tests for that library could be found at `tendermint/rpc/lib` directory.
## Configuration
Set the `laddr` config parameter under `[rpc]` table in the `$TMHOME/config.toml` file or the `--rpc.laddr` command-line flag to the desired protocol://host:port setting. Default: `tcp://0.0.0.0:46657`.
## Arguments
Arguments which expect strings or byte arrays may be passed as quoted strings, like `"abc"` or as `0x`-prefixed strings, like `0x616263`.
## URI/HTTP
```bash
curl 'localhost:46657/broadcast_tx_sync?tx="abc"'
```
> Response:
```json
{
"error": "",
"result": {
"hash": "2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF",
"log": "",
"data": "",
"code": 0
},
"id": "",
"jsonrpc": "2.0"
}
```
The first entry in the result-array (`96`) is the method this response correlates with. `96` refers to "ResultTypeBroadcastTx", see [responses.go](https://github.com/tendermint/tendermint/blob/master/rpc/core/types/responses.go) for a complete overview.
## JSONRPC/HTTP
JSONRPC requests can be POST'd to the root RPC endpoint via HTTP (e.g. `http://localhost:46657/`).
```json
{
"method": "broadcast_tx_sync",
"jsonrpc": "2.0",
"params": [ "abc" ],
"id": "dontcare"
}
```
## JSONRPC/websockets
JSONRPC requests can be made via websocket. The websocket endpoint is at `/websocket`, e.g. `localhost:46657/websocket`. Asynchronous RPC functions like event `subscribe` and `unsubscribe` are only available via websockets.
## More Examples
See the various bash tests using curl in `test/`, and examples using the `Go` API in `rpc/client/`.
## Get the list
An HTTP Get request to the root RPC endpoint shows a list of available endpoints.
```bash
curl 'localhost:46657'
```
> Response:
```plain
Available endpoints:
/abci_info
/dump_consensus_state
/genesis
/net_info
/num_unconfirmed_txs
/status
/unconfirmed_txs
/unsafe_flush_mempool
/unsafe_stop_cpu_profiler
/validators
Endpoints that require arguments:
/abci_query?path=_&data=_&prove=_
/block?height=_
/blockchain?minHeight=_&maxHeight=_
/broadcast_tx_async?tx=_
/broadcast_tx_commit?tx=_
/broadcast_tx_sync?tx=_
/commit?height=_
/dial_seeds?seeds=_
/subscribe?event=_
/tx?hash=_&prove=_
/unsafe_start_cpu_profiler?filename=_
/unsafe_write_heap_profile?filename=_
/unsubscribe?event=_
```
# Endpoints
*/
package core

+ 8
- 0
rpc/core/doc_template.txt View File

@ -0,0 +1,8 @@
{{with .PDoc}}
{{comment_md .Doc}}
{{example_html $ ""}}
{{range .Funcs}}{{$name_html := html .Name}}## [{{$name_html}}]({{posLink_url $ .Decl}})
{{comment_md .Doc}}{{end}}
{{end}}
---

+ 54
- 0
rpc/core/events.go View File

@ -6,6 +6,33 @@ import (
"github.com/tendermint/tendermint/types"
)
// Subscribe for events via WebSocket.
//
// ```go
// import "github.com/tendermint/tendermint/types"
//
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// result, err := client.AddListenerForEvent(types.EventStringNewBlock())
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {},
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
//
// ### Query Parameters
//
// | Parameter | Type | Default | Required | Description |
// |-----------+--------+---------+----------+-------------|
// | event | string | "" | true | Event name |
//
// <aside class="notice">WebSocket only</aside>
func Subscribe(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.ResultSubscribe, error) {
logger.Info("Subscribe to event", "remote", wsCtx.GetRemoteAddr(), "event", event)
types.AddListenerForEvent(wsCtx.GetEventSwitch(), wsCtx.GetRemoteAddr(), event, func(msg types.TMEventData) {
@ -17,6 +44,33 @@ func Subscribe(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.ResultSubscri
return &ctypes.ResultSubscribe{}, nil
}
// Unsubscribe from events via WebSocket.
//
// ```go
// import 'github.com/tendermint/tendermint/types'
//
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// result, err := client.RemoveListenerForEvent(types.EventStringNewBlock())
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {},
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
//
// ### Query Parameters
//
// | Parameter | Type | Default | Required | Description |
// |-----------+--------+---------+----------+-------------|
// | event | string | "" | true | Event name |
//
// <aside class="notice">WebSocket only</aside>
func Unsubscribe(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.ResultUnsubscribe, error) {
logger.Info("Unsubscribe to event", "remote", wsCtx.GetRemoteAddr(), "event", event)
wsCtx.GetEventSwitch().RemoveListenerForEvent(event, wsCtx.GetRemoteAddr())


+ 150
- 1
rpc/core/mempool.go View File

@ -14,6 +14,37 @@ import (
// NOTE: tx should be signed, but this is only checked at the app level (not by Tendermint!)
// Returns right away, with no response
//
// ```shell
// curl 'localhost:46657/broadcast_tx_async?tx="123"'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// result, err := client.BroadcastTxAsync("123")
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "hash": "E39AAB7A537ABAA237831742DCE1117F187C3C52",
// "log": "",
// "data": "",
// "code": 0
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
//
// ### Query Parameters
//
// | Parameter | Type | Default | Required | Description |
// |-----------+------+---------+----------+-----------------|
// | tx | Tx | nil | true | The transaction |
func BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
err := mempool.CheckTx(tx, nil)
if err != nil {
@ -22,7 +53,38 @@ func BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
return &ctypes.ResultBroadcastTx{Hash: tx.Hash()}, nil
}
// Returns with the response from CheckTx
// Returns with the response from CheckTx.
//
// ```shell
// curl 'localhost:46657/broadcast_tx_sync?tx="456"'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// result, err := client.BroadcastTxSync("456")
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "jsonrpc": "2.0",
// "id": "",
// "result": {
// "code": 0,
// "data": "",
// "log": "",
// "hash": "0D33F2F03A5234F38706E43004489E061AC40A2E"
// },
// "error": ""
// }
// ```
//
// ### Query Parameters
//
// | Parameter | Type | Default | Required | Description |
// |-----------+------+---------+----------+-----------------|
// | tx | Tx | nil | true | The transaction |
func BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
resCh := make(chan *abci.Response, 1)
err := mempool.CheckTx(tx, func(res *abci.Response) {
@ -45,6 +107,45 @@ func BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
// or if we timeout waiting for tx to commit.
// If CheckTx or DeliverTx fail, no error will be returned, but the returned result
// will contain a non-OK ABCI code.
//
// ```shell
// curl 'localhost:46657/broadcast_tx_commit?tx="789"'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// result, err := client.BroadcastTxCommit("789")
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "height": 26682,
// "hash": "75CA0F856A4DA078FC4911580360E70CEFB2EBEE",
// "deliver_tx": {
// "log": "",
// "data": "",
// "code": 0
// },
// "check_tx": {
// "log": "",
// "data": "",
// "code": 0
// }
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
//
// ### Query Parameters
//
// | Parameter | Type | Default | Required | Description |
// |-----------+------+---------+----------+-----------------|
// | tx | Tx | nil | true | The transaction |
func BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
// subscribe to tx being committed in block
@ -104,11 +205,59 @@ func BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
panic("Should never happen!")
}
// Get unconfirmed transactions including their number.
//
// ```shell
// curl 'localhost:46657/unconfirmed_txs'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// result, err := client.UnconfirmedTxs()
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "txs": [],
// "n_txs": 0
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func UnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
txs := mempool.Reap(-1)
return &ctypes.ResultUnconfirmedTxs{len(txs), txs}, nil
}
// Get number of unconfirmed transactions.
//
// ```shell
// curl 'localhost:46657/num_unconfirmed_txs'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// result, err := client.UnconfirmedTxs()
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "txs": null,
// "n_txs": 0
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
return &ctypes.ResultUnconfirmedTxs{N: mempool.Size()}, nil
}

+ 64
- 7
rpc/core/net.go View File

@ -6,8 +6,33 @@ import (
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
//-----------------------------------------------------------------------------
// Get network info.
//
// ```shell
// curl 'localhost:46657/net_info'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// info, err := client.NetInfo()
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "peers": [],
// "listeners": [
// "Listener(@10.0.2.15:46656)"
// ],
// "listening": true
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func NetInfo() (*ctypes.ResultNetInfo, error) {
listening := p2pSwitch.IsListening()
listeners := []string{}
@ -29,9 +54,6 @@ func NetInfo() (*ctypes.ResultNetInfo, error) {
}, nil
}
//-----------------------------------------------------------------------------
// Dial given list of seeds
func UnsafeDialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) {
if len(seeds) == 0 {
@ -46,8 +68,43 @@ func UnsafeDialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) {
return &ctypes.ResultDialSeeds{"Dialing seeds in progress. See /net_info for details"}, nil
}
//-----------------------------------------------------------------------------
// Get genesis file.
//
// ```shell
// curl 'localhost:46657/genesis'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// genesis, err := client.Genesis()
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "genesis": {
// "app_hash": "",
// "validators": [
// {
// "name": "",
// "amount": 10,
// "pub_key": {
// "data": "68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D",
// "type": "ed25519"
// }
// }
// ],
// "chain_id": "test-chain-6UTNIN",
// "genesis_time": "2017-05-29T15:05:41.671Z"
// }
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func Genesis() (*ctypes.ResultGenesis, error) {
return &ctypes.ResultGenesis{genDoc}, nil
}

+ 47
- 0
rpc/core/status.go View File

@ -6,6 +6,53 @@ import (
"github.com/tendermint/tendermint/types"
)
// Get Tendermint status including node info, pubkey, latest block
// hash, app hash, block height and time.
//
// ```shell
// curl 'localhost:46657/status'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// result, err := client.Status()
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "latest_block_time": 1.49631773695e+18,
// "latest_block_height": 22924,
// "latest_app_hash": "9D16177BC71E445476174622EA559715C293740C",
// "latest_block_hash": "75B36EEF96C277A592D8B14867098C58F68BB180",
// "pub_key": {
// "data": "68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D",
// "type": "ed25519"
// },
// "node_info": {
// "other": [
// "wire_version=0.6.2",
// "p2p_version=0.5.0",
// "consensus_version=v1/0.2.2",
// "rpc_version=0.7.0/3",
// "tx_index=on",
// "rpc_addr=tcp://0.0.0.0:46657"
// ],
// "version": "0.10.0-rc1-aa22bd84",
// "listen_addr": "10.0.2.15:46656",
// "remote_addr": "",
// "network": "test-chain-6UTNIN",
// "moniker": "anonymous",
// "pub_key": "659B9E54DD6EF9FEF28FAD40629AF0E4BD3C2563BB037132B054A176E00F1D94"
// }
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
func Status() (*ctypes.ResultStatus, error) {
latestHeight := blockStore.Height()
var (


+ 57
- 2
rpc/core/tx.go View File

@ -8,9 +8,64 @@ import (
"github.com/tendermint/tendermint/types"
)
// Tx allow user to query the transaction results. `nil` could mean the
// transaction is in the mempool, invalidated, or was not send in the first
// Tx allows you to query the transaction results. `nil` could mean the
// transaction is in the mempool, invalidated, or was not sent in the first
// place.
//
// ```shell
// curl "localhost:46657/tx?hash=0x2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF"
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// tx, err := client.Tx([]byte("2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF"), true)
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "proof": {
// "Proof": {
// "aunts": []
// },
// "Data": "YWJjZA==",
// "RootHash": "2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF",
// "Total": 1,
// "Index": 0
// },
// "tx": "YWJjZA==",
// "tx_result": {
// "log": "",
// "data": "",
// "code": 0
// },
// "index": 0,
// "height": 52
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
//
// Returns a transaction matching the given transaction hash.
//
// ### Query Parameters
//
// | Parameter | Type | Default | Required | Description |
// |-----------+--------+---------+----------+-----------------------------------------------------------|
// | hash | []byte | nil | true | The transaction hash |
// | prove | bool | false | false | Include a proof of the transaction inclusion in the block |
//
// ### Returns
//
// - `proof`: the `types.TxProof` object
// - `tx`: `[]byte` - the transaction
// - `tx_result`: the `abci.Result` object
// - `index`: `int` - index of the transaction
// - `height`: `int` - height of the block where this transaction was in
func Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
// if index is disabled, return error


Loading…
Cancel
Save