OSDN Git Service

Nodeinfo handshake information modification (#68)
authoryahtoo <yahtoo.ma@gmail.com>
Fri, 17 May 2019 04:19:22 +0000 (12:19 +0800)
committerPaladz <yzhu101@uottawa.ca>
Fri, 17 May 2019 04:19:22 +0000 (12:19 +0800)
* Nodeinfo handshake information modification

* Add moniker to config file

* Add node info test file

* Del useless code

* opz code format

* opz log print

cmd/bytomd/commands/run_node.go
config/config.go
config/toml.go
netsync/handle.go
node/node.go
p2p/node_info.go
p2p/node_info_test.go [new file with mode: 0644]
p2p/peer.go
p2p/switch.go

index fc8e864..a129307 100644 (file)
@@ -85,11 +85,8 @@ func runNode(cmd *cobra.Command, args []string) error {
                log.WithFields(log.Fields{"module": logModule, "err": err}).Fatal("failed to start node")
        }
 
                log.WithFields(log.Fields{"module": logModule, "err": err}).Fatal("failed to start node")
        }
 
-       nodeInfo := n.NodeInfo()
        log.WithFields(log.Fields{
                "module":   logModule,
        log.WithFields(log.Fields{
                "module":   logModule,
-               "version":  nodeInfo.Version,
-               "network":  nodeInfo.Network,
                "duration": time.Since(startTime),
        }).Info("start node complete")
 
                "duration": time.Since(startTime),
        }).Info("start node complete")
 
index 3b4b28b..03d7d6f 100644 (file)
@@ -85,9 +85,6 @@ type BaseConfig struct {
        // This should be set in viper so it can unmarshal into this struct
        RootDir string `mapstructure:"home"`
 
        // This should be set in viper so it can unmarshal into this struct
        RootDir string `mapstructure:"home"`
 
-       //The alias of the node
-       NodeAlias string `mapstructure:"node_alias"`
-
        //The ID of the network to json
        ChainID string `mapstructure:"chain_id"`
 
        //The ID of the network to json
        ChainID string `mapstructure:"chain_id"`
 
@@ -131,8 +128,6 @@ func DefaultBaseConfig() BaseConfig {
                DBBackend:         "leveldb",
                DBPath:            "data",
                KeysPath:          "keystore",
                DBBackend:         "leveldb",
                DBPath:            "data",
                KeysPath:          "keystore",
-               NodeAlias:         "",
-               // CipherServiceProvider: "ed25519",
        }
 }
 
        }
 }
 
index 1d9b0c6..ceb448c 100644 (file)
@@ -24,7 +24,7 @@ var defaultConfigTmpl = `# This is a TOML config file.
 fast_sync = true
 db_backend = "leveldb"
 api_addr = "0.0.0.0:9888"
 fast_sync = true
 db_backend = "leveldb"
 api_addr = "0.0.0.0:9888"
-node_alias = ""
+moniker = ""
 `
 
 var mainNetConfigTmpl = `chain_id = "mainnet"
 `
 
 var mainNetConfigTmpl = `chain_id = "mainnet"
index 70702c9..ce10e1a 100644 (file)
@@ -44,7 +44,6 @@ type Switch interface {
        AddReactor(name string, reactor p2p.Reactor) p2p.Reactor
        AddBannedPeer(string) error
        StopPeerGracefully(string)
        AddReactor(name string, reactor p2p.Reactor) p2p.Reactor
        AddBannedPeer(string) error
        StopPeerGracefully(string)
-       NodeInfo() *p2p.NodeInfo
        Start() (bool, error)
        Stop() bool
        IsListening() bool
        Start() (bool, error)
        Stop() bool
        IsListening() bool
@@ -333,10 +332,6 @@ func (sm *SyncManager) IsListening() bool {
        return sm.sw.IsListening()
 }
 
        return sm.sw.IsListening()
 }
 
-func (sm *SyncManager) NodeInfo() *p2p.NodeInfo {
-       return sm.sw.NodeInfo()
-}
-
 func (sm *SyncManager) PeerCount() int {
        if sm.config.VaultMode {
                return 0
 func (sm *SyncManager) PeerCount() int {
        if sm.config.VaultMode {
                return 0
index 92a4593..b590a7c 100644 (file)
@@ -29,7 +29,6 @@ import (
        "github.com/vapor/mining/cpuminer"
        "github.com/vapor/net/websocket"
        "github.com/vapor/netsync"
        "github.com/vapor/mining/cpuminer"
        "github.com/vapor/net/websocket"
        "github.com/vapor/netsync"
-       "github.com/vapor/p2p"
        "github.com/vapor/protocol"
        w "github.com/vapor/wallet"
 )
        "github.com/vapor/protocol"
        w "github.com/vapor/wallet"
 )
@@ -257,7 +256,3 @@ func (n *Node) RunForever() {
                n.Stop()
        })
 }
                n.Stop()
        })
 }
-
-func (n *Node) NodeInfo() *p2p.NodeInfo {
-       return n.syncManager.NodeInfo()
-}
index 2e52e31..5caed49 100644 (file)
@@ -3,92 +3,88 @@ package p2p
 import (
        "fmt"
        "net"
 import (
        "fmt"
        "net"
-       "strconv"
 
        "github.com/tendermint/go-crypto"
 
        cfg "github.com/vapor/config"
        "github.com/vapor/consensus"
 
        "github.com/tendermint/go-crypto"
 
        cfg "github.com/vapor/config"
        "github.com/vapor/consensus"
+       "github.com/vapor/errors"
        "github.com/vapor/version"
 )
 
 const maxNodeInfoSize = 10240 // 10Kb
 
        "github.com/vapor/version"
 )
 
 const maxNodeInfoSize = 10240 // 10Kb
 
+var (
+       errDiffMajorVersion = errors.New("Peer is on a different major version.")
+       errDiffNetwork      = errors.New("Peer is on a different network name.")
+       errDiffNetworkID    = errors.New("Peer has different network ID.")
+)
+
 //NodeInfo peer node info
 type NodeInfo struct {
        PubKey  crypto.PubKeyEd25519 `json:"pub_key"`
        Moniker string               `json:"moniker"`
        Network string               `json:"network"`
        //NetworkID used to isolate subnets with same network name
 //NodeInfo peer node info
 type NodeInfo struct {
        PubKey  crypto.PubKeyEd25519 `json:"pub_key"`
        Moniker string               `json:"moniker"`
        Network string               `json:"network"`
        //NetworkID used to isolate subnets with same network name
-       NetworkID  uint64 `json:"network_id"`
-       RemoteAddr string `json:"remote_addr"`
-       ListenAddr string `json:"listen_addr"`
-       Version    string `json:"version"` // major.minor.revision
+       NetworkID   uint64                `json:"network_id"`
+       RemoteAddr  string                `json:"remote_addr"`
+       ListenAddr  string                `json:"listen_addr"`
+       Version     string                `json:"version"` // major.minor.revision
+       ServiceFlag consensus.ServiceFlag `json:"service_flag"`
        // other application specific data
        // other application specific data
-       //field 0: node service flags. field 1: node alias.
        Other []string `json:"other"`
 }
 
 func NewNodeInfo(config *cfg.Config, pubkey crypto.PubKeyEd25519, listenAddr string, netID uint64) *NodeInfo {
        Other []string `json:"other"`
 }
 
 func NewNodeInfo(config *cfg.Config, pubkey crypto.PubKeyEd25519, listenAddr string, netID uint64) *NodeInfo {
-       other := []string{strconv.FormatUint(uint64(consensus.DefaultServices), 10)}
-       if config.NodeAlias != "" {
-               other = append(other, config.NodeAlias)
-       }
        return &NodeInfo{
        return &NodeInfo{
-               PubKey:     pubkey,
-               Moniker:    config.Moniker,
-               Network:    config.ChainID,
-               NetworkID:  netID,
-               ListenAddr: listenAddr,
-               Version:    version.Version,
-               Other:      other,
+               PubKey:      pubkey,
+               Moniker:     config.Moniker,
+               Network:     config.ChainID,
+               NetworkID:   netID,
+               ListenAddr:  listenAddr,
+               Version:     version.Version,
+               ServiceFlag: consensus.DefaultServices,
        }
 }
 
        }
 }
 
+type VersionCompatibleWith func(remoteVerStr string) (bool, error)
+
 // CompatibleWith checks if two NodeInfo are compatible with eachother.
 // CONTRACT: two nodes are compatible if the major version matches and network match
 // CompatibleWith checks if two NodeInfo are compatible with eachother.
 // CONTRACT: two nodes are compatible if the major version matches and network match
-func (info *NodeInfo) CompatibleWith(other *NodeInfo) error {
+func (info *NodeInfo) compatibleWith(other *NodeInfo, versionCompatibleWith VersionCompatibleWith) error {
        if info.Network != other.Network {
        if info.Network != other.Network {
-               return fmt.Errorf("Peer is on a different network. Peer network: %v, node network: %v", other.Network, info.Network)
+               return errors.Wrapf(errDiffNetwork, "Peer network: %v, node network: %v", other.Network, info.Network)
        }
 
        if info.NetworkID != other.NetworkID {
        }
 
        if info.NetworkID != other.NetworkID {
-               return fmt.Errorf("Network id dismatch. Peer network id: %v, node network id: %v", other.NetworkID, info.NetworkID)
+               return errors.Wrapf(errDiffNetworkID, "Peer network id: %v, node network id: %v", other.NetworkID, info.NetworkID)
        }
 
        }
 
-       compatible, err := version.CompatibleWith(other.Version)
+       compatible, err := versionCompatibleWith(other.Version)
        if err != nil {
                return err
        }
        if err != nil {
                return err
        }
+
        if !compatible {
        if !compatible {
-               return fmt.Errorf("Peer is on a different major version. Peer version: %v, node version: %v", other.Version, info.Version)
+               return errors.Wrapf(errDiffMajorVersion, "Peer version: %v, node version: %v", other.Version, info.Version)
        }
 
        return nil
 }
 
        }
 
        return nil
 }
 
-func (info *NodeInfo) getPubkey() crypto.PubKeyEd25519 {
-       return info.PubKey
-}
-
-//ListenHost peer listener ip address
-func (info *NodeInfo) listenHost() string {
+//listenHost peer listener ip address
+func (info NodeInfo) listenHost() string {
        host, _, _ := net.SplitHostPort(info.ListenAddr)
        return host
 }
 
        host, _, _ := net.SplitHostPort(info.ListenAddr)
        return host
 }
 
-//RemoteAddrHost peer external ip address
-func (info *NodeInfo) remoteAddrHost() string {
+//remoteAddrHost peer external ip address
+func (info NodeInfo) remoteAddrHost() string {
        host, _, _ := net.SplitHostPort(info.RemoteAddr)
        return host
 }
 
        host, _, _ := net.SplitHostPort(info.RemoteAddr)
        return host
 }
 
-//GetNetwork get node info network field
-func (info *NodeInfo) GetNetwork() string {
-       return info.Network
-}
-
 //String representation
 func (info NodeInfo) String() string {
 //String representation
 func (info NodeInfo) String() string {
-       return fmt.Sprintf("NodeInfo{pk: %v, moniker: %v, network: %v [listen %v], version: %v (%v)}", info.PubKey, info.Moniker, info.Network, info.ListenAddr, info.Version, info.Other)
+       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)
 }
 }
diff --git a/p2p/node_info_test.go b/p2p/node_info_test.go
new file mode 100644 (file)
index 0000000..f31aa9f
--- /dev/null
@@ -0,0 +1,63 @@
+package p2p
+
+import (
+       "bytes"
+       "reflect"
+       "testing"
+
+       "github.com/davecgh/go-spew/spew"
+       "github.com/tendermint/go-crypto"
+       "github.com/tendermint/go-wire"
+
+       "github.com/vapor/errors"
+)
+
+func mockCompatibleWithFalse(remoteVerStr string) (bool, error) {
+       return false, nil
+}
+
+func mockCompatibleWithTrue(remoteVerStr string) (bool, error) {
+       return true, nil
+}
+
+func TestCompatibleWith(t *testing.T) {
+       nodeInfo := &NodeInfo{Network: "testnet", NetworkID: 0x888}
+
+       cases := []struct {
+               other                 *NodeInfo
+               versionCompatibleWith VersionCompatibleWith
+               err                   error
+       }{
+               {other: &NodeInfo{Network: "mainnet", NetworkID: 0x888}, versionCompatibleWith: mockCompatibleWithTrue, err: errDiffNetwork},
+               {other: &NodeInfo{Network: "testnet", NetworkID: 0x888}, versionCompatibleWith: mockCompatibleWithTrue, err: nil},
+               {other: &NodeInfo{Network: "testnet", NetworkID: 0x999}, versionCompatibleWith: mockCompatibleWithTrue, err: errDiffNetworkID},
+               {other: &NodeInfo{Network: "testnet", NetworkID: 0x888}, versionCompatibleWith: mockCompatibleWithFalse, err: errDiffMajorVersion},
+       }
+
+       for i, c := range cases {
+               if err := nodeInfo.compatibleWith(c.other, c.versionCompatibleWith); errors.Root(err) != c.err {
+                       t.Fatalf("index:%d node info compatible test err want:%s result:%s", i, c.err, err)
+               }
+       }
+}
+
+func TestNodeInfoWriteRead(t *testing.T) {
+       nodeInfo := &NodeInfo{PubKey: crypto.GenPrivKeyEd25519().PubKey().Unwrap().(crypto.PubKeyEd25519), Moniker: "bytomd", Network: "mainnet", NetworkID: 0x888, RemoteAddr: "127.0.0.2:0", ListenAddr: "127.0.0.1:0", Version: "1.1.0-test", ServiceFlag: 10, Other: []string{"abc", "bcd"}}
+       n, err, err1 := new(int), new(error), new(error)
+       buf := new(bytes.Buffer)
+
+       wire.WriteBinary(nodeInfo, buf, n, err)
+       if *err != nil {
+               t.Fatal(*err)
+       }
+
+       peerNodeInfo := new(NodeInfo)
+       wire.ReadBinary(peerNodeInfo, buf, maxNodeInfoSize, new(int), err1)
+       if *err1 != nil {
+               t.Fatal(*err1)
+       }
+
+       if !reflect.DeepEqual(*nodeInfo, *peerNodeInfo) {
+               t.Fatal("TestNodeInfoWriteRead err", spew.Sdump(nodeInfo), spew.Sdump(peerNodeInfo))
+       }
+}
index cdb609d..11641b8 100644 (file)
@@ -4,7 +4,6 @@ import (
        "fmt"
        "net"
        "reflect"
        "fmt"
        "net"
        "reflect"
-       "strconv"
        "time"
 
        "github.com/btcsuite/go-socks/socks"
        "time"
 
        "github.com/btcsuite/go-socks/socks"
@@ -110,6 +109,11 @@ func newPeerConn(rawConn net.Conn, outbound bool, ourNodePrivKey crypto.PrivKeyE
                return nil, errors.Wrap(err, "Error creating peer")
        }
 
                return nil, errors.Wrap(err, "Error creating peer")
        }
 
+       // Remove deadline
+       if err := rawConn.SetDeadline(time.Time{}); err != nil {
+               return nil, err
+       }
+
        return &peerConn{
                config:   config,
                outbound: outbound,
        return &peerConn{
                config:   config,
                outbound: outbound,
@@ -206,15 +210,8 @@ func (p *Peer) Send(chID byte, msg interface{}) bool {
 
 // ServiceFlag return the ServiceFlag of this peer
 func (p *Peer) ServiceFlag() consensus.ServiceFlag {
 
 // ServiceFlag return the ServiceFlag of this peer
 func (p *Peer) ServiceFlag() consensus.ServiceFlag {
-       services := consensus.SFFullNode
-       if len(p.Other) == 0 {
-               return services
-       }
-
-       if serviceFlag, err := strconv.ParseUint(p.Other[0], 10, 64); err == nil {
-               services = consensus.ServiceFlag(serviceFlag)
-       }
-       return services
+       // ServiceFlag return the ServiceFlag of this peer
+       return p.NodeInfo.ServiceFlag
 }
 
 // String representation.
 }
 
 // String representation.
index c64a69e..d70fa75 100644 (file)
@@ -151,6 +151,7 @@ func newSwitch(config *cfg.Config, discv discv, lanDiscv lanDiscv, blacklistDB d
        sw.AddListener(l)
        sw.BaseService = *cmn.NewBaseService(nil, "P2P Switch", sw)
        trust.Init()
        sw.AddListener(l)
        sw.BaseService = *cmn.NewBaseService(nil, "P2P Switch", sw)
        trust.Init()
+       log.WithFields(log.Fields{"module": logModule, "nodeInfo": sw.nodeInfo}).Info("init p2p network")
        return sw, nil
 }
 
        return sw, nil
 }
 
@@ -220,7 +221,8 @@ func (sw *Switch) AddPeer(pc *peerConn, isLAN bool) error {
        if err := version.Status.CheckUpdate(sw.nodeInfo.Version, peerNodeInfo.Version, peerNodeInfo.RemoteAddr); err != nil {
                return err
        }
        if err := version.Status.CheckUpdate(sw.nodeInfo.Version, peerNodeInfo.Version, peerNodeInfo.RemoteAddr); err != nil {
                return err
        }
-       if err := sw.nodeInfo.CompatibleWith(peerNodeInfo); err != nil {
+
+       if err := sw.nodeInfo.compatibleWith(peerNodeInfo, version.CompatibleWith); err != nil {
                return err
        }
 
                return err
        }
 
@@ -336,12 +338,6 @@ func (sw *Switch) NumPeers() (lan, outbound, inbound, dialing int) {
        return
 }
 
        return
 }
 
-// NodeInfo returns the switch's NodeInfo.
-// NOTE: Not goroutine safe.
-func (sw *Switch) NodeInfo() *NodeInfo {
-       return sw.nodeInfo
-}
-
 //Peers return switch peerset
 func (sw *Switch) Peers() *PeerSet {
        return sw.peers
 //Peers return switch peerset
 func (sw *Switch) Peers() *PeerSet {
        return sw.peers
@@ -466,7 +462,7 @@ func (sw *Switch) filterConnByPeer(peer *Peer) error {
                return err
        }
 
                return err
        }
 
-       if sw.nodeInfo.getPubkey().Equals(peer.PubKey().Wrap()) {
+       if sw.nodeInfo.PubKey.Equals(peer.PubKey().Wrap()) {
                return ErrConnectSelf
        }
 
                return ErrConnectSelf
        }
 
@@ -515,7 +511,7 @@ func (sw *Switch) dialPeers(addresses []*NetAddress) {
 
        var wg sync.WaitGroup
        for _, address := range addresses {
 
        var wg sync.WaitGroup
        for _, address := range addresses {
-               if sw.NodeInfo().ListenAddr == address.String() {
+               if sw.nodeInfo.ListenAddr == address.String() {
                        continue
                }
                if dialling := sw.IsDialing(address); dialling {
                        continue
                }
                if dialling := sw.IsDialing(address); dialling {