github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/api/nodeinfo.go (about)

     1  package api
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  
     7  	"github.com/bytom/bytom/config"
     8  	"github.com/bytom/bytom/errors"
     9  	"github.com/bytom/bytom/netsync/peers"
    10  	"github.com/bytom/bytom/p2p"
    11  	"github.com/bytom/bytom/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  	HighestHeight uint64       `json:"highest_height"`
    28  	NetWorkID     string       `json:"network_id"`
    29  	Version       *VersionInfo `json:"version_info"`
    30  }
    31  
    32  // getNetInfo return network information
    33  func (a *API) getNetInfo() Response {
    34  	highestBlockHeight := a.chain.BestBlockHeight()
    35  	if bestPeer := a.sync.BestPeer(); bestPeer != nil {
    36  		if bestPeer.Height > highestBlockHeight {
    37  			highestBlockHeight = bestPeer.Height
    38  		}
    39  	}
    40  	return NewSuccessResponse(&NetInfo{
    41  		Listening:     a.sync.IsListening(),
    42  		Syncing:       !a.sync.IsCaughtUp(),
    43  		Mining:        a.blockProposer.IsProposing(),
    44  		NodeXPub:      config.CommonConfig.PrivateKey().XPub().String(),
    45  		PeerCount:     a.sync.PeerCount(),
    46  		HighestHeight: highestBlockHeight,
    47  		NetWorkID:     a.sync.GetNetwork(),
    48  		Version: &VersionInfo{
    49  			Version: version.Version,
    50  			Update:  version.Status.VersionStatus(),
    51  			NewVer:  version.Status.MaxVerSeen(),
    52  		},
    53  	})
    54  }
    55  
    56  // return the currently connected peers with net address
    57  func (a *API) getPeerInfoByAddr(addr string) *peers.PeerInfo {
    58  	peerInfos := a.sync.GetPeerInfos()
    59  	for _, peerInfo := range peerInfos {
    60  		if peerInfo.RemoteAddr == addr {
    61  			return peerInfo
    62  		}
    63  	}
    64  	return nil
    65  }
    66  
    67  // disconnect peer by the peer id
    68  func (a *API) disconnectPeerById(peerID string) error {
    69  	return a.sync.StopPeer(peerID)
    70  }
    71  
    72  // connect peer b y net address
    73  func (a *API) connectPeerByIpAndPort(ip string, port uint16) (*peers.PeerInfo, error) {
    74  	netIp := net.ParseIP(ip)
    75  	if netIp == nil {
    76  		return nil, errors.New("invalid ip address")
    77  	}
    78  
    79  	addr := p2p.NewNetAddressIPPort(netIp, port)
    80  
    81  	if err := a.sync.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  // isMining return is in mining or not
    92  func (a *API) isMining() Response {
    93  	IsMining := map[string]bool{"is_mining": a.blockProposer.IsProposing()}
    94  	return NewSuccessResponse(IsMining)
    95  }
    96  
    97  // IsMining return mining status
    98  func (a *API) IsMining() bool {
    99  	return a.blockProposer.IsProposing()
   100  }
   101  
   102  // return the peers of current node
   103  func (a *API) listPeers() Response {
   104  	return NewSuccessResponse(a.sync.GetPeerInfos())
   105  }
   106  
   107  // disconnect peer
   108  func (a *API) disconnectPeer(ctx context.Context, ins struct {
   109  	PeerID string `json:"peer_id"`
   110  }) Response {
   111  	if err := a.disconnectPeerById(ins.PeerID); err != nil {
   112  		return NewErrorResponse(err)
   113  	}
   114  	return NewSuccessResponse(nil)
   115  }
   116  
   117  // connect peer by ip and port
   118  func (a *API) connectPeer(ctx context.Context, ins struct {
   119  	Ip   string `json:"ip"`
   120  	Port uint16 `json:"port"`
   121  }) Response {
   122  	if peer, err := a.connectPeerByIpAndPort(ins.Ip, ins.Port); err != nil {
   123  		return NewErrorResponse(err)
   124  	} else {
   125  		return NewSuccessResponse(peer)
   126  	}
   127  }