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"
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"`
20 // NetInfo indicate net information
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"`
33 // GetNodeInfo return net information
34 func (a *API) GetNodeInfo() *NetInfo {
35 nodeXPub := cfg.CommonConfig.PrivateKey().XPub()
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(),
50 if bestPeer := a.sync.BestPeer(); bestPeer != nil {
51 info.HighestBlock = bestPeer.Height
53 if info.CurrentBlock > info.HighestBlock {
54 info.HighestBlock = info.CurrentBlock
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 {
70 // disconnect peer by the peer id
71 func (a *API) disconnectPeerById(peerID string) error {
72 return a.sync.StopPeer(peerID)
75 // connect peer b y net address
76 func (a *API) connectPeerByIpAndPort(ip string, port uint16) (*peers.PeerInfo, error) {
77 netIp := net.ParseIP(ip)
79 return nil, errors.New("invalid ip address")
82 addr := p2p.NewNetAddressIPPort(netIp, port)
84 if err := a.sync.DialPeerWithAddress(addr); err != nil {
85 return nil, errors.Wrap(err, "can not connect to the address")
87 peer := a.getPeerInfoByAddr(addr.String())
89 return nil, errors.New("the peer is disconnected again")
94 // getNetInfo return network information
95 func (a *API) getNetInfo() Response {
96 return NewSuccessResponse(a.GetNodeInfo())
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)
105 // IsProposing return mining status
106 func (a *API) IsMining() bool {
107 return a.blockProposer.IsProposing()
110 // return the peers of current node
111 func (a *API) listPeers() Response {
112 return NewSuccessResponse(a.sync.GetPeerInfos())
116 func (a *API) disconnectPeer(ctx context.Context, ins struct {
117 PeerID string `json:"peer_id"`
119 if err := a.disconnectPeerById(ins.PeerID); err != nil {
120 return NewErrorResponse(err)
122 return NewSuccessResponse(nil)
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"`
130 if peer, err := a.connectPeerByIpAndPort(ins.Ip, ins.Port); err != nil {
131 return NewErrorResponse(err)
133 return NewSuccessResponse(peer)