github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/api/nodeinfo.go (about)

     1  package api
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  
     7  	"github.com/bytom/bytom/errors"
     8  	"github.com/bytom/bytom/netsync"
     9  	"github.com/bytom/bytom/p2p"
    10  	"github.com/bytom/bytom/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) *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  
    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  }