OSDN Git Service

c0b55c1edad5a14965b8a9ab2c2a7aeb10dcc2bb
[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"
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.Switch().IsListening(),
35                 Syncing:      !a.sync.IsCaughtUp(),
36                 Mining:       a.cpuMiner.IsMining(),
37                 PeerCount:    len(a.sync.Switch().Peers().List()),
38                 CurrentBlock: a.chain.BestBlockHeight(),
39                 NetWorkID:    a.sync.NodeInfo().Network,
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) *netsync.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) (*netsync.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         sw := a.sync.Switch()
80
81         if err := sw.DialPeerWithAddress(addr); err != nil {
82                 return nil, errors.Wrap(err, "can not connect to the address")
83         }
84         peer := a.getPeerInfoByAddr(addr.String())
85         if peer == nil {
86                 return nil, errors.New("the peer is disconnected again")
87         }
88         return peer, nil
89 }
90
91 // getNetInfo return network information
92 func (a *API) getNetInfo() Response {
93         return NewSuccessResponse(a.GetNodeInfo())
94 }
95
96 // isMining return is in mining or not
97 func (a *API) isMining() Response {
98         IsMining := map[string]bool{"is_mining": a.IsMining()}
99         return NewSuccessResponse(IsMining)
100 }
101
102 // IsMining return mining status
103 func (a *API) IsMining() bool {
104         return a.cpuMiner.IsMining()
105 }
106
107 // return the peers of current node
108 func (a *API) listPeers() Response {
109         return NewSuccessResponse(a.sync.GetPeerInfos())
110 }
111
112 // disconnect peer
113 func (a *API) disconnectPeer(ctx context.Context, ins struct {
114         PeerID string `json:"peer_id"`
115 }) Response {
116         if err := a.disconnectPeerById(ins.PeerID); err != nil {
117                 return NewErrorResponse(err)
118         }
119         return NewSuccessResponse(nil)
120 }
121
122 // connect peer by ip and port
123 func (a *API) connectPeer(ctx context.Context, ins struct {
124         Ip   string `json:"ip"`
125         Port uint16 `json:"port"`
126 }) Response {
127         if peer, err := a.connectPeerByIpAndPort(ins.Ip, ins.Port); err != nil {
128                 return NewErrorResponse(err)
129         } else {
130                 return NewSuccessResponse(peer)
131         }
132 }