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.

137 lines
3.6 KiB

  1. package core
  2. import (
  3. "bytes"
  4. "time"
  5. cmn "github.com/tendermint/tendermint/libs/common"
  6. "github.com/tendermint/tendermint/p2p"
  7. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  8. sm "github.com/tendermint/tendermint/state"
  9. "github.com/tendermint/tendermint/types"
  10. )
  11. // Get Tendermint status including node info, pubkey, latest block
  12. // hash, app hash, block height and time.
  13. //
  14. // ```shell
  15. // curl 'localhost:26657/status'
  16. // ```
  17. //
  18. // ```go
  19. // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket")
  20. // result, err := client.Status()
  21. // ```
  22. //
  23. // > The above command returns JSON structured like this:
  24. //
  25. // ```json
  26. // {
  27. // "jsonrpc": "2.0",
  28. // "id": "",
  29. // "result": {
  30. // "node_info": {
  31. // "id": "53729852020041b956e86685e24394e0bee4373f",
  32. // "listen_addr": "10.0.2.15:26656",
  33. // "network": "test-chain-Y1OHx6",
  34. // "version": "0.24.0-2ce1abc2",
  35. // "channels": "4020212223303800",
  36. // "moniker": "ubuntu-xenial",
  37. // "other": {
  38. // "amino_version": "0.12.0",
  39. // "p2p_version": "0.5.0",
  40. // "consensus_version": "v1/0.2.2",
  41. // "rpc_version": "0.7.0/3",
  42. // "tx_index": "on",
  43. // "rpc_addr": "tcp://0.0.0.0:26657"
  44. // }
  45. // },
  46. // "sync_info": {
  47. // "latest_block_hash": "F51538DA498299F4C57AC8162AAFA0254CE08286",
  48. // "latest_app_hash": "0000000000000000",
  49. // "latest_block_height": "18",
  50. // "latest_block_time": "2018-09-17T11:42:19.149920551Z",
  51. // "catching_up": false
  52. // },
  53. // "validator_info": {
  54. // "address": "D9F56456D7C5793815D0E9AF07C3A355D0FC64FD",
  55. // "pub_key": {
  56. // "type": "tendermint/PubKeyEd25519",
  57. // "value": "wVxKNtEsJmR4vvh651LrVoRguPs+6yJJ9Bz174gw9DM="
  58. // },
  59. // "voting_power": "10"
  60. // }
  61. // }
  62. // }
  63. // ```
  64. func Status() (*ctypes.ResultStatus, error) {
  65. var latestHeight int64 = -1
  66. if consensusReactor.FastSync() {
  67. latestHeight = blockStore.Height()
  68. } else {
  69. latestHeight = consensusState.GetLastHeight()
  70. }
  71. var (
  72. latestBlockMeta *types.BlockMeta
  73. latestBlockHash cmn.HexBytes
  74. latestAppHash cmn.HexBytes
  75. latestBlockTimeNano int64
  76. )
  77. if latestHeight != 0 {
  78. latestBlockMeta = blockStore.LoadBlockMeta(latestHeight)
  79. latestBlockHash = latestBlockMeta.BlockID.Hash
  80. latestAppHash = latestBlockMeta.Header.AppHash
  81. latestBlockTimeNano = latestBlockMeta.Header.Time.UnixNano()
  82. }
  83. latestBlockTime := time.Unix(0, latestBlockTimeNano)
  84. var votingPower int64
  85. if val := validatorAtHeight(latestHeight); val != nil {
  86. votingPower = val.VotingPower
  87. }
  88. result := &ctypes.ResultStatus{
  89. NodeInfo: p2pTransport.NodeInfo().(p2p.DefaultNodeInfo),
  90. SyncInfo: ctypes.SyncInfo{
  91. LatestBlockHash: latestBlockHash,
  92. LatestAppHash: latestAppHash,
  93. LatestBlockHeight: latestHeight,
  94. LatestBlockTime: latestBlockTime,
  95. CatchingUp: consensusReactor.FastSync(),
  96. },
  97. ValidatorInfo: ctypes.ValidatorInfo{
  98. Address: pubKey.Address(),
  99. PubKey: pubKey,
  100. VotingPower: votingPower,
  101. },
  102. }
  103. return result, nil
  104. }
  105. func validatorAtHeight(h int64) *types.Validator {
  106. privValAddress := pubKey.Address()
  107. // If we're still at height h, search in the current validator set.
  108. lastBlockHeight, vals := consensusState.GetValidators()
  109. if lastBlockHeight == h {
  110. for _, val := range vals {
  111. if bytes.Equal(val.Address, privValAddress) {
  112. return val
  113. }
  114. }
  115. }
  116. // If we've moved to the next height, retrieve the validator set from DB.
  117. if lastBlockHeight > h {
  118. vals, err := sm.LoadValidators(stateDB, h)
  119. if err != nil {
  120. return nil // should not happen
  121. }
  122. _, val := vals.GetByAddress(privValAddress)
  123. return val
  124. }
  125. return nil
  126. }