OSDN Git Service

5caed49dd64475f5958c4e0528f68796db695f94
[bytom/vapor.git] / p2p / node_info.go
1 package p2p
2
3 import (
4         "fmt"
5         "net"
6
7         "github.com/tendermint/go-crypto"
8
9         cfg "github.com/vapor/config"
10         "github.com/vapor/consensus"
11         "github.com/vapor/errors"
12         "github.com/vapor/version"
13 )
14
15 const maxNodeInfoSize = 10240 // 10Kb
16
17 var (
18         errDiffMajorVersion = errors.New("Peer is on a different major version.")
19         errDiffNetwork      = errors.New("Peer is on a different network name.")
20         errDiffNetworkID    = errors.New("Peer has different network ID.")
21 )
22
23 //NodeInfo peer node info
24 type NodeInfo struct {
25         PubKey  crypto.PubKeyEd25519 `json:"pub_key"`
26         Moniker string               `json:"moniker"`
27         Network string               `json:"network"`
28         //NetworkID used to isolate subnets with same network name
29         NetworkID   uint64                `json:"network_id"`
30         RemoteAddr  string                `json:"remote_addr"`
31         ListenAddr  string                `json:"listen_addr"`
32         Version     string                `json:"version"` // major.minor.revision
33         ServiceFlag consensus.ServiceFlag `json:"service_flag"`
34         // other application specific data
35         Other []string `json:"other"`
36 }
37
38 func NewNodeInfo(config *cfg.Config, pubkey crypto.PubKeyEd25519, listenAddr string, netID uint64) *NodeInfo {
39         return &NodeInfo{
40                 PubKey:      pubkey,
41                 Moniker:     config.Moniker,
42                 Network:     config.ChainID,
43                 NetworkID:   netID,
44                 ListenAddr:  listenAddr,
45                 Version:     version.Version,
46                 ServiceFlag: consensus.DefaultServices,
47         }
48 }
49
50 type VersionCompatibleWith func(remoteVerStr string) (bool, error)
51
52 // CompatibleWith checks if two NodeInfo are compatible with eachother.
53 // CONTRACT: two nodes are compatible if the major version matches and network match
54 func (info *NodeInfo) compatibleWith(other *NodeInfo, versionCompatibleWith VersionCompatibleWith) error {
55         if info.Network != other.Network {
56                 return errors.Wrapf(errDiffNetwork, "Peer network: %v, node network: %v", other.Network, info.Network)
57         }
58
59         if info.NetworkID != other.NetworkID {
60                 return errors.Wrapf(errDiffNetworkID, "Peer network id: %v, node network id: %v", other.NetworkID, info.NetworkID)
61         }
62
63         compatible, err := versionCompatibleWith(other.Version)
64         if err != nil {
65                 return err
66         }
67
68         if !compatible {
69                 return errors.Wrapf(errDiffMajorVersion, "Peer version: %v, node version: %v", other.Version, info.Version)
70         }
71
72         return nil
73 }
74
75 //listenHost peer listener ip address
76 func (info NodeInfo) listenHost() string {
77         host, _, _ := net.SplitHostPort(info.ListenAddr)
78         return host
79 }
80
81 //remoteAddrHost peer external ip address
82 func (info NodeInfo) remoteAddrHost() string {
83         host, _, _ := net.SplitHostPort(info.RemoteAddr)
84         return host
85 }
86
87 //String representation
88 func (info NodeInfo) String() string {
89         return fmt.Sprintf("NodeInfo{pk: %v, moniker: %v, network: %v [listen %v],networkID: %x, service: %v,version: %v (%v)}", info.PubKey, info.Moniker, info.Network, info.ListenAddr, info.NetworkID, info.ServiceFlag, info.Version, info.Other)
90 }