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.

111 lines
3.2 KiB

7 years ago
  1. package core
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/tendermint/tendermint/p2p"
  6. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  7. rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
  8. )
  9. // NetInfo returns network info.
  10. // More: https://docs.tendermint.com/master/rpc/#/Info/net_info
  11. func (env *Environment) NetInfo(ctx *rpctypes.Context) (*ctypes.ResultNetInfo, error) {
  12. peersList := env.P2PPeers.Peers().List()
  13. peers := make([]ctypes.Peer, 0, len(peersList))
  14. for _, peer := range peersList {
  15. peers = append(peers, ctypes.Peer{
  16. NodeInfo: peer.NodeInfo(),
  17. IsOutbound: peer.IsOutbound(),
  18. ConnectionStatus: peer.Status(),
  19. RemoteIP: peer.RemoteIP().String(),
  20. })
  21. }
  22. // TODO: Should we include PersistentPeers and Seeds in here?
  23. // PRO: useful info
  24. // CON: privacy
  25. return &ctypes.ResultNetInfo{
  26. Listening: env.P2PTransport.IsListening(),
  27. Listeners: env.P2PTransport.Listeners(),
  28. NPeers: len(peers),
  29. Peers: peers,
  30. }, nil
  31. }
  32. // UnsafeDialSeeds dials the given seeds (comma-separated id@IP:PORT).
  33. func (env *Environment) UnsafeDialSeeds(ctx *rpctypes.Context, seeds []string) (*ctypes.ResultDialSeeds, error) {
  34. if len(seeds) == 0 {
  35. return &ctypes.ResultDialSeeds{}, fmt.Errorf("%w: no seeds provided", ctypes.ErrInvalidRequest)
  36. }
  37. env.Logger.Info("DialSeeds", "seeds", seeds)
  38. if err := env.P2PPeers.DialPeersAsync(seeds); err != nil {
  39. return &ctypes.ResultDialSeeds{}, err
  40. }
  41. return &ctypes.ResultDialSeeds{Log: "Dialing seeds in progress. See /net_info for details"}, nil
  42. }
  43. // UnsafeDialPeers dials the given peers (comma-separated id@IP:PORT),
  44. // optionally making them persistent.
  45. func (env *Environment) UnsafeDialPeers(
  46. ctx *rpctypes.Context,
  47. peers []string,
  48. persistent, unconditional, private bool) (*ctypes.ResultDialPeers, error) {
  49. if len(peers) == 0 {
  50. return &ctypes.ResultDialPeers{}, fmt.Errorf("%w: no peers provided", ctypes.ErrInvalidRequest)
  51. }
  52. ids, err := getIDs(peers)
  53. if err != nil {
  54. return &ctypes.ResultDialPeers{}, err
  55. }
  56. env.Logger.Info("DialPeers", "peers", peers, "persistent",
  57. persistent, "unconditional", unconditional, "private", private)
  58. if persistent {
  59. if err := env.P2PPeers.AddPersistentPeers(peers); err != nil {
  60. return &ctypes.ResultDialPeers{}, err
  61. }
  62. }
  63. if private {
  64. if err := env.P2PPeers.AddPrivatePeerIDs(ids); err != nil {
  65. return &ctypes.ResultDialPeers{}, err
  66. }
  67. }
  68. if unconditional {
  69. if err := env.P2PPeers.AddUnconditionalPeerIDs(ids); err != nil {
  70. return &ctypes.ResultDialPeers{}, err
  71. }
  72. }
  73. if err := env.P2PPeers.DialPeersAsync(peers); err != nil {
  74. return &ctypes.ResultDialPeers{}, err
  75. }
  76. return &ctypes.ResultDialPeers{Log: "Dialing peers in progress. See /net_info for details"}, nil
  77. }
  78. // Genesis returns genesis file.
  79. // More: https://docs.tendermint.com/master/rpc/#/Info/genesis
  80. func (env *Environment) Genesis(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) {
  81. return &ctypes.ResultGenesis{Genesis: env.GenDoc}, nil
  82. }
  83. func getIDs(peers []string) ([]string, error) {
  84. ids := make([]string, 0, len(peers))
  85. for _, peer := range peers {
  86. spl := strings.Split(peer, "@")
  87. if len(spl) != 2 {
  88. return nil, p2p.ErrNetAddressNoID{Addr: peer}
  89. }
  90. ids = append(ids, spl[0])
  91. }
  92. return ids, nil
  93. }