OSDN Git Service

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