You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
8.3 KiB

  1. package core
  2. import (
  3. cm "github.com/tendermint/tendermint/consensus"
  4. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  5. sm "github.com/tendermint/tendermint/state"
  6. "github.com/tendermint/tendermint/types"
  7. )
  8. // Get the validator set at the given block height.
  9. // If no height is provided, it will fetch the current validator set.
  10. //
  11. // ```shell
  12. // curl 'localhost:26657/validators'
  13. // ```
  14. //
  15. // ```go
  16. // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket")
  17. // state, err := client.Validators()
  18. // ```
  19. //
  20. // The above command returns JSON structured like this:
  21. //
  22. // ```json
  23. // {
  24. // "error": "",
  25. // "result": {
  26. // "validators": [
  27. // {
  28. // "accum": "0",
  29. // "voting_power": "10",
  30. // "pub_key": {
  31. // "data": "68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D",
  32. // "type": "ed25519"
  33. // },
  34. // "address": "E89A51D60F68385E09E716D353373B11F8FACD62"
  35. // }
  36. // ],
  37. // "block_height": "5241"
  38. // },
  39. // "id": "",
  40. // "jsonrpc": "2.0"
  41. // }
  42. // ```
  43. func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
  44. // The latest validator that we know is the
  45. // NextValidator of the last block.
  46. height := consensusState.GetState().LastBlockHeight + 1
  47. height, err := getHeight(height, heightPtr)
  48. if err != nil {
  49. return nil, err
  50. }
  51. validators, err := sm.LoadValidators(stateDB, height)
  52. if err != nil {
  53. return nil, err
  54. }
  55. return &ctypes.ResultValidators{height, validators.Validators}, nil
  56. }
  57. // DumpConsensusState dumps consensus state.
  58. // UNSTABLE
  59. //
  60. // ```shell
  61. // curl 'localhost:26657/dump_consensus_state'
  62. // ```
  63. //
  64. // ```go
  65. // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket")
  66. // state, err := client.DumpConsensusState()
  67. // ```
  68. //
  69. // The above command returns JSON structured like this:
  70. //
  71. // ```json
  72. // {
  73. // "jsonrpc": "2.0",
  74. // "id": "",
  75. // "result": {
  76. // "round_state": {
  77. // "height": "7185",
  78. // "round": "0",
  79. // "step": "1",
  80. // "start_time": "2018-05-12T13:57:28.440293621-07:00",
  81. // "commit_time": "2018-05-12T13:57:27.440293621-07:00",
  82. // "validators": {
  83. // "validators": [
  84. // {
  85. // "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244",
  86. // "pub_key": {
  87. // "type": "tendermint/PubKeyEd25519",
  88. // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
  89. // },
  90. // "voting_power": "10",
  91. // "accum": "0"
  92. // }
  93. // ],
  94. // "proposer": {
  95. // "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244",
  96. // "pub_key": {
  97. // "type": "tendermint/PubKeyEd25519",
  98. // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
  99. // },
  100. // "voting_power": "10",
  101. // "accum": "0"
  102. // }
  103. // },
  104. // "proposal": null,
  105. // "proposal_block": null,
  106. // "proposal_block_parts": null,
  107. // "locked_round": "0",
  108. // "locked_block": null,
  109. // "locked_block_parts": null,
  110. // "valid_round": "0",
  111. // "valid_block": null,
  112. // "valid_block_parts": null,
  113. // "votes": [
  114. // {
  115. // "round": "0",
  116. // "prevotes": "_",
  117. // "precommits": "_"
  118. // }
  119. // ],
  120. // "commit_round": "-1",
  121. // "last_commit": {
  122. // "votes": [
  123. // "Vote{0:B5B3D40BE539 7184/00/2(Precommit) 14F946FA7EF0 /702B1B1A602A.../ @ 2018-05-12T20:57:27.342Z}"
  124. // ],
  125. // "votes_bit_array": "x",
  126. // "peer_maj_23s": {}
  127. // },
  128. // "last_validators": {
  129. // "validators": [
  130. // {
  131. // "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244",
  132. // "pub_key": {
  133. // "type": "tendermint/PubKeyEd25519",
  134. // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
  135. // },
  136. // "voting_power": "10",
  137. // "accum": "0"
  138. // }
  139. // ],
  140. // "proposer": {
  141. // "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244",
  142. // "pub_key": {
  143. // "type": "tendermint/PubKeyEd25519",
  144. // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
  145. // },
  146. // "voting_power": "10",
  147. // "accum": "0"
  148. // }
  149. // }
  150. // },
  151. // "peers": [
  152. // {
  153. // "node_address": "30ad1854af22506383c3f0e57fb3c7f90984c5e8@172.16.63.221:26656",
  154. // "peer_state": {
  155. // "round_state": {
  156. // "height": "7185",
  157. // "round": "0",
  158. // "step": "1",
  159. // "start_time": "2018-05-12T13:57:27.438039872-07:00",
  160. // "proposal": false,
  161. // "proposal_block_parts_header": {
  162. // "total": "0",
  163. // "hash": ""
  164. // },
  165. // "proposal_block_parts": null,
  166. // "proposal_pol_round": "-1",
  167. // "proposal_pol": "_",
  168. // "prevotes": "_",
  169. // "precommits": "_",
  170. // "last_commit_round": "0",
  171. // "last_commit": "x",
  172. // "catchup_commit_round": "-1",
  173. // "catchup_commit": "_"
  174. // },
  175. // "stats": {
  176. // "last_vote_height": "7184",
  177. // "votes": "255",
  178. // "last_block_part_height": "7184",
  179. // "block_parts": "255"
  180. // }
  181. // }
  182. // }
  183. // ]
  184. // }
  185. // }
  186. // ```
  187. func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
  188. // Get Peer consensus states.
  189. peers := p2pPeers.Peers().List()
  190. peerStates := make([]ctypes.PeerStateInfo, len(peers))
  191. for i, peer := range peers {
  192. peerState := peer.Get(types.PeerStateKey).(*cm.PeerState)
  193. peerStateJSON, err := peerState.ToJSON()
  194. if err != nil {
  195. return nil, err
  196. }
  197. peerStates[i] = ctypes.PeerStateInfo{
  198. // Peer basic info.
  199. NodeAddress: peer.NodeInfo().NetAddress().String(),
  200. // Peer consensus state.
  201. PeerState: peerStateJSON,
  202. }
  203. }
  204. // Get self round state.
  205. roundState, err := consensusState.GetRoundStateJSON()
  206. if err != nil {
  207. return nil, err
  208. }
  209. return &ctypes.ResultDumpConsensusState{roundState, peerStates}, nil
  210. }
  211. // ConsensusState returns a concise summary of the consensus state.
  212. // UNSTABLE
  213. //
  214. // ```shell
  215. // curl 'localhost:26657/consensus_state'
  216. // ```
  217. //
  218. // ```go
  219. // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket")
  220. // state, err := client.ConsensusState()
  221. // ```
  222. //
  223. // The above command returns JSON structured like this:
  224. //
  225. // ```json
  226. //{
  227. // "jsonrpc": "2.0",
  228. // "id": "",
  229. // "result": {
  230. // "round_state": {
  231. // "height/round/step": "9336/0/1",
  232. // "start_time": "2018-05-14T10:25:45.72595357-04:00",
  233. // "proposal_block_hash": "",
  234. // "locked_block_hash": "",
  235. // "valid_block_hash": "",
  236. // "height_vote_set": [
  237. // {
  238. // "round": "0",
  239. // "prevotes": [
  240. // "nil-Vote"
  241. // ],
  242. // "prevotes_bit_array": "BA{1:_} 0/10 = 0.00",
  243. // "precommits": [
  244. // "nil-Vote"
  245. // ],
  246. // "precommits_bit_array": "BA{1:_} 0/10 = 0.00"
  247. // }
  248. // ]
  249. // }
  250. // }
  251. //}
  252. //```
  253. func ConsensusState() (*ctypes.ResultConsensusState, error) {
  254. // Get self round state.
  255. bz, err := consensusState.GetRoundStateSimpleJSON()
  256. return &ctypes.ResultConsensusState{bz}, err
  257. }
  258. // Get the consensus parameters at the given block height.
  259. // If no height is provided, it will fetch the current consensus params.
  260. //
  261. // ```shell
  262. // curl 'localhost:26657/consensus_params'
  263. // ```
  264. //
  265. // ```go
  266. // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket")
  267. // state, err := client.ConsensusParams()
  268. // ```
  269. //
  270. // The above command returns JSON structured like this:
  271. //
  272. // ```json
  273. // {
  274. // "jsonrpc": "2.0",
  275. // "id": "",
  276. // "result": {
  277. // "block_height": "1",
  278. // "consensus_params": {
  279. // "block_size_params": {
  280. // "max_txs_bytes": "22020096",
  281. // "max_gas": "-1"
  282. // },
  283. // "evidence_params": {
  284. // "max_age": "100000"
  285. // }
  286. // }
  287. // }
  288. // }
  289. // ```
  290. func ConsensusParams(heightPtr *int64) (*ctypes.ResultConsensusParams, error) {
  291. height := consensusState.GetState().LastBlockHeight + 1
  292. height, err := getHeight(height, heightPtr)
  293. if err != nil {
  294. return nil, err
  295. }
  296. consensusparams, err := sm.LoadConsensusParams(stateDB, height)
  297. if err != nil {
  298. return nil, err
  299. }
  300. return &ctypes.ResultConsensusParams{BlockHeight: height, ConsensusParams: consensusparams}, nil
  301. }