OSDN Git Service

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