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.

252 lines
6.3 KiB

7 years ago
  1. package core
  2. import (
  3. "fmt"
  4. "github.com/pkg/errors"
  5. "github.com/tendermint/tendermint/p2p"
  6. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  7. )
  8. // Get network info.
  9. //
  10. // ```shell
  11. // curl 'localhost:26657/net_info'
  12. // ```
  13. //
  14. // ```go
  15. // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket")
  16. // err := client.Start()
  17. // if err != nil {
  18. // // handle error
  19. // }
  20. // defer client.Stop()
  21. // info, err := client.NetInfo()
  22. // ```
  23. //
  24. // > The above command returns JSON structured like this:
  25. //
  26. // ```json
  27. // {
  28. // "jsonrpc": "2.0",
  29. // "id": "",
  30. // "result": {
  31. // "listening": true,
  32. // "listeners": [
  33. // "Listener(@)"
  34. // ],
  35. // "n_peers": "3",
  36. // "peers": [
  37. // {
  38. // "node_info": {
  39. // "protocol_version": {
  40. // "p2p": "7",
  41. // "block": "8",
  42. // "app": "1"
  43. // },
  44. // "id": "93529da3435c090d02251a050342b6a488d4ab56",
  45. // "listen_addr": "tcp://0.0.0.0:26656",
  46. // "network": "chain-RFo6qC",
  47. // "version": "0.30.0",
  48. // "channels": "4020212223303800",
  49. // "moniker": "fc89e4ed23f2",
  50. // "other": {
  51. // "tx_index": "on",
  52. // "rpc_address": "tcp://0.0.0.0:26657"
  53. // }
  54. // },
  55. // "is_outbound": true,
  56. // "connection_status": {
  57. // "Duration": "3475230558",
  58. // "SendMonitor": {
  59. // "Active": true,
  60. // "Start": "2019-02-14T12:40:47.52Z",
  61. // "Duration": "3480000000",
  62. // "Idle": "240000000",
  63. // "Bytes": "4512",
  64. // "Samples": "9",
  65. // "InstRate": "1338",
  66. // "CurRate": "2046",
  67. // "AvgRate": "1297",
  68. // "PeakRate": "6570",
  69. // "BytesRem": "0",
  70. // "TimeRem": "0",
  71. // "Progress": 0
  72. // },
  73. // "RecvMonitor": {
  74. // "Active": true,
  75. // "Start": "2019-02-14T12:40:47.52Z",
  76. // "Duration": "3480000000",
  77. // "Idle": "280000000",
  78. // "Bytes": "4489",
  79. // "Samples": "10",
  80. // "InstRate": "1821",
  81. // "CurRate": "1663",
  82. // "AvgRate": "1290",
  83. // "PeakRate": "5512",
  84. // "BytesRem": "0",
  85. // "TimeRem": "0",
  86. // "Progress": 0
  87. // },
  88. // "Channels": [
  89. // {
  90. // "ID": 48,
  91. // "SendQueueCapacity": "1",
  92. // "SendQueueSize": "0",
  93. // "Priority": "5",
  94. // "RecentlySent": "0"
  95. // },
  96. // {
  97. // "ID": 64,
  98. // "SendQueueCapacity": "1000",
  99. // "SendQueueSize": "0",
  100. // "Priority": "10",
  101. // "RecentlySent": "14"
  102. // },
  103. // {
  104. // "ID": 32,
  105. // "SendQueueCapacity": "100",
  106. // "SendQueueSize": "0",
  107. // "Priority": "5",
  108. // "RecentlySent": "619"
  109. // },
  110. // {
  111. // "ID": 33,
  112. // "SendQueueCapacity": "100",
  113. // "SendQueueSize": "0",
  114. // "Priority": "10",
  115. // "RecentlySent": "1363"
  116. // },
  117. // {
  118. // "ID": 34,
  119. // "SendQueueCapacity": "100",
  120. // "SendQueueSize": "0",
  121. // "Priority": "5",
  122. // "RecentlySent": "2145"
  123. // },
  124. // {
  125. // "ID": 35,
  126. // "SendQueueCapacity": "2",
  127. // "SendQueueSize": "0",
  128. // "Priority": "1",
  129. // "RecentlySent": "0"
  130. // },
  131. // {
  132. // "ID": 56,
  133. // "SendQueueCapacity": "1",
  134. // "SendQueueSize": "0",
  135. // "Priority": "5",
  136. // "RecentlySent": "0"
  137. // },
  138. // {
  139. // "ID": 0,
  140. // "SendQueueCapacity": "10",
  141. // "SendQueueSize": "0",
  142. // "Priority": "1",
  143. // "RecentlySent": "10"
  144. // }
  145. // ]
  146. // },
  147. // "remote_ip": "192.167.10.3"
  148. // },
  149. // ...
  150. // }
  151. // ```
  152. func NetInfo() (*ctypes.ResultNetInfo, error) {
  153. out, in, _ := p2pPeers.NumPeers()
  154. peers := make([]ctypes.Peer, 0, out+in)
  155. for _, peer := range p2pPeers.Peers().List() {
  156. nodeInfo, ok := peer.NodeInfo().(p2p.DefaultNodeInfo)
  157. if !ok {
  158. return nil, fmt.Errorf("peer.NodeInfo() is not DefaultNodeInfo")
  159. }
  160. peers = append(peers, ctypes.Peer{
  161. NodeInfo: nodeInfo,
  162. IsOutbound: peer.IsOutbound(),
  163. ConnectionStatus: peer.Status(),
  164. RemoteIP: peer.RemoteIP().String(),
  165. })
  166. }
  167. // TODO: Should we include PersistentPeers and Seeds in here?
  168. // PRO: useful info
  169. // CON: privacy
  170. return &ctypes.ResultNetInfo{
  171. Listening: p2pTransport.IsListening(),
  172. Listeners: p2pTransport.Listeners(),
  173. NPeers: len(peers),
  174. Peers: peers,
  175. }, nil
  176. }
  177. func UnsafeDialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) {
  178. if len(seeds) == 0 {
  179. return &ctypes.ResultDialSeeds{}, errors.New("No seeds provided")
  180. }
  181. // starts go routines to dial each peer after random delays
  182. logger.Info("DialSeeds", "addrBook", addrBook, "seeds", seeds)
  183. err := p2pPeers.DialPeersAsync(addrBook, seeds, false)
  184. if err != nil {
  185. return &ctypes.ResultDialSeeds{}, err
  186. }
  187. return &ctypes.ResultDialSeeds{Log: "Dialing seeds in progress. See /net_info for details"}, nil
  188. }
  189. func UnsafeDialPeers(peers []string, persistent bool) (*ctypes.ResultDialPeers, error) {
  190. if len(peers) == 0 {
  191. return &ctypes.ResultDialPeers{}, errors.New("No peers provided")
  192. }
  193. // starts go routines to dial each peer after random delays
  194. logger.Info("DialPeers", "addrBook", addrBook, "peers", peers, "persistent", persistent)
  195. err := p2pPeers.DialPeersAsync(addrBook, peers, persistent)
  196. if err != nil {
  197. return &ctypes.ResultDialPeers{}, err
  198. }
  199. return &ctypes.ResultDialPeers{Log: "Dialing peers in progress. See /net_info for details"}, nil
  200. }
  201. // Get genesis file.
  202. //
  203. // ```shell
  204. // curl 'localhost:26657/genesis'
  205. // ```
  206. //
  207. // ```go
  208. // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket")
  209. // err := client.Start()
  210. // if err != nil {
  211. // // handle error
  212. // }
  213. // defer client.Stop()
  214. // genesis, err := client.Genesis()
  215. // ```
  216. //
  217. // > The above command returns JSON structured like this:
  218. //
  219. // ```json
  220. // {
  221. // "error": "",
  222. // "result": {
  223. // "genesis": {
  224. // "app_hash": "",
  225. // "validators": [
  226. // {
  227. // "name": "",
  228. // "power": "10",
  229. // "pub_key": {
  230. // "data": "68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D",
  231. // "type": "ed25519"
  232. // }
  233. // }
  234. // ],
  235. // "chain_id": "test-chain-6UTNIN",
  236. // "genesis_time": "2017-05-29T15:05:41.671Z"
  237. // }
  238. // },
  239. // "id": "",
  240. // "jsonrpc": "2.0"
  241. // }
  242. // ```
  243. func Genesis() (*ctypes.ResultGenesis, error) {
  244. return &ctypes.ResultGenesis{Genesis: genDoc}, nil
  245. }