OSDN Git Service

Merge pull request #1128 from Bytom/dev
[bytom/bytom.git] / api / nodeinfo.go
1 package api
2
3 import (
4         "net"
5         "context"
6
7         "github.com/bytom/version"
8         "github.com/bytom/netsync"
9         "github.com/bytom/errors"
10         "github.com/bytom/p2p"
11 )
12
13 // NetInfo indicate net information
14 type NetInfo struct {
15         Listening    bool   `json:"listening"`
16         Syncing      bool   `json:"syncing"`
17         Mining       bool   `json:"mining"`
18         PeerCount    int    `json:"peer_count"`
19         CurrentBlock uint64 `json:"current_block"`
20         HighestBlock uint64 `json:"highest_block"`
21         NetWorkID    string `json:"network_id"`
22         Version      string `json:"version"`
23 }
24
25 // GetNodeInfo return net information
26 func (a *API) GetNodeInfo() *NetInfo {
27         info := &NetInfo{
28                 Listening:    a.sync.Switch().IsListening(),
29                 Syncing:      a.sync.BlockKeeper().IsCaughtUp(),
30                 Mining:       a.cpuMiner.IsMining(),
31                 PeerCount:    len(a.sync.Switch().Peers().List()),
32                 CurrentBlock: a.chain.BestBlockHeight(),
33                 NetWorkID:    a.sync.NodeInfo().Network,
34                 Version:      version.Version,
35         }
36         _, info.HighestBlock = a.sync.Peers().BestPeer()
37         if info.CurrentBlock > info.HighestBlock {
38                 info.HighestBlock = info.CurrentBlock
39         }
40         return info
41 }
42
43
44 // return the currently connected peers with net address
45 func (a *API) getPeerInfoByAddr(addr string) *netsync.PeerInfo {
46         peerInfos := a.sync.Peers().GetPeerInfos()
47         for _, peerInfo := range peerInfos {
48                 if peerInfo.RemoteAddr == addr {
49                         return peerInfo
50                 }
51         }
52         return nil
53 }
54
55 // disconnect peer by the peer id
56 func (a *API) disconnectPeerById(peerId string) error {
57         if peer, ok := a.sync.Peers().Peer(peerId); ok {
58                 swPeer := peer.GetPeer()
59                 a.sync.Switch().StopPeerGracefully(swPeer)
60                 return nil
61         }
62         return errors.New("peerId not exist")
63 }
64
65 // connect peer b y net address
66 func (a *API) connectPeerByIpAndPort(ip string, port uint16) (*netsync.PeerInfo, error) {
67         netIp := net.ParseIP(ip)
68         if netIp == nil {
69                 return nil, errors.New("invalid ip address")
70         }
71
72         addr := p2p.NewNetAddressIPPort(netIp, port)
73         sw := a.sync.Switch()
74
75         if err := sw.DialPeerWithAddress(addr); err != nil {
76                 return nil, errors.Wrap(err, "can not connect to the address")
77         }
78         peer := a.getPeerInfoByAddr(addr.String())
79         if peer == nil {
80                 return nil, errors.New("the peer is disconnected again")
81         }
82         return peer, nil
83 }
84
85 // getNetInfo return network information
86 func (a *API) getNetInfo() Response {
87         return NewSuccessResponse(a.GetNodeInfo())
88 }
89
90 // isMining return is in mining or not
91 func (a *API) isMining() Response {
92         IsMining := map[string]bool{"is_mining": a.IsMining()}
93         return NewSuccessResponse(IsMining)
94 }
95
96 // IsMining return mining status
97 func (a *API) IsMining() bool {
98         return a.cpuMiner.IsMining()
99 }
100
101 // return the peers of current node
102 func (a *API) listPeers() Response {
103         return NewSuccessResponse(a.sync.Peers().GetPeerInfos())
104 }
105
106 // disconnect peer
107 func (a *API) disconnectPeer(ctx context.Context, ins struct {
108         PeerId string `json:"peerId"`
109 }) Response {
110         if err := a.disconnectPeerById(ins.PeerId); err != nil {
111                 return NewErrorResponse(err)
112         }
113         return NewSuccessResponse(nil)
114 }
115
116 // connect peer by ip and port
117 func (a *API) connectPeer(ctx context.Context, ins struct {
118         Ip   string `json:"ip"`
119         Port uint16 `json:"port"`
120 }) Response {
121         if peer, err := a.connectPeerByIpAndPort(ins.Ip, ins.Port); err != nil {
122                 return NewErrorResponse(err)
123         } else {
124                 return NewSuccessResponse(peer)
125         }
126 }