7 log "github.com/sirupsen/logrus"
9 "github.com/bytom/vapor/common"
10 cfg "github.com/bytom/vapor/config"
11 "github.com/bytom/vapor/consensus"
12 "github.com/bytom/vapor/crypto"
13 "github.com/bytom/vapor/errors"
14 "github.com/bytom/vapor/netsync/peers"
15 "github.com/bytom/vapor/p2p"
16 "github.com/bytom/vapor/version"
19 type VersionInfo struct {
20 Version string `json:"version"`
21 Update uint16 `json:"update"` // 0: no update; 1: small update; 2: significant update
22 NewVer string `json:"new_version"`
25 // NetInfo indicate net information
27 Listening bool `json:"listening"`
28 Syncing bool `json:"syncing"`
29 Mining bool `json:"mining"`
30 NodeXPub string `json:"node_xpub"`
31 FedAddress string `json:"federation_address"`
32 PeerCount int `json:"peer_count"`
33 CurrentBlock uint64 `json:"current_block"`
34 IrreversibleBlock uint64 `json:"irreversible_block"`
35 HighestBlock uint64 `json:"highest_block"`
36 NetWorkID string `json:"network_id"`
37 Version *VersionInfo `json:"version_info"`
40 // GetNodeInfo return net information
41 func (a *API) GetNodeInfo() *NetInfo {
42 nodeXPub := cfg.CommonConfig.PrivateKey().XPub()
44 signScript := cfg.FederationPMultiSigScript(cfg.CommonConfig)
45 scriptHash := crypto.Sha256(signScript)
46 address, err := common.NewAddressWitnessScriptHash(scriptHash, consensus.BytomMainNetParams(&consensus.ActiveNetParams))
48 log.WithFields(log.Fields{"module": logModule, "err": err}).Fatal("Failed to get federation address.")
52 Listening: a.sync.IsListening(),
53 Syncing: !a.sync.IsCaughtUp(),
54 Mining: a.blockProposer.IsProposing(),
55 NodeXPub: nodeXPub.String(),
56 FedAddress: address.EncodeAddress(),
57 PeerCount: a.sync.PeerCount(),
58 CurrentBlock: a.chain.BestBlockHeight(),
59 IrreversibleBlock: a.chain.LastIrreversibleHeader().Height,
60 NetWorkID: a.sync.GetNetwork(),
61 Version: &VersionInfo{
62 Version: version.Version,
63 Update: version.Status.VersionStatus(),
64 NewVer: version.Status.MaxVerSeen(),
67 if bestPeer := a.sync.BestPeer(); bestPeer != nil {
68 info.HighestBlock = bestPeer.Height
70 if info.CurrentBlock > info.HighestBlock {
71 info.HighestBlock = info.CurrentBlock
76 // return the currently connected peers with net address
77 func (a *API) getPeerInfoByAddr(addr string) *peers.PeerInfo {
78 peerInfos := a.sync.GetPeerInfos()
79 for _, peerInfo := range peerInfos {
80 if peerInfo.RemoteAddr == addr {
87 // disconnect peer by the peer id
88 func (a *API) disconnectPeerById(peerID string) error {
89 return a.sync.StopPeer(peerID)
92 // connect peer b y net address
93 func (a *API) connectPeerByIpAndPort(ip string, port uint16) (*peers.PeerInfo, error) {
94 netIp := net.ParseIP(ip)
96 return nil, errors.New("invalid ip address")
99 addr := p2p.NewNetAddressIPPort(netIp, port)
101 if err := a.sync.DialPeerWithAddress(addr); err != nil {
102 return nil, errors.Wrap(err, "can not connect to the address")
104 peer := a.getPeerInfoByAddr(addr.String())
106 return nil, errors.New("the peer is disconnected again")
111 // getNetInfo return network information
112 func (a *API) getNetInfo() Response {
113 return NewSuccessResponse(a.GetNodeInfo())
116 // isMining return is in mining or not
117 func (a *API) isMining() Response {
118 IsMining := map[string]bool{"is_mining": a.IsMining()}
119 return NewSuccessResponse(IsMining)
122 // IsProposing return mining status
123 func (a *API) IsMining() bool {
124 return a.blockProposer.IsProposing()
127 // return the peers of current node
128 func (a *API) listPeers() Response {
129 return NewSuccessResponse(a.sync.GetPeerInfos())
133 func (a *API) disconnectPeer(ctx context.Context, ins struct {
134 PeerID string `json:"peer_id"`
136 if err := a.disconnectPeerById(ins.PeerID); err != nil {
137 return NewErrorResponse(err)
139 return NewSuccessResponse(nil)
142 // connect peer by ip and port
143 func (a *API) connectPeer(ctx context.Context, ins struct {
144 Ip string `json:"ip"`
145 Port uint16 `json:"port"`
147 if peer, err := a.connectPeerByIpAndPort(ins.Ip, ins.Port); err != nil {
148 return NewErrorResponse(err)
150 return NewSuccessResponse(peer)