OSDN Git Service

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