From 9340ef4f86c71ff18da4ec7d3d3aae9aadf4ba76 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Wed, 30 Jan 2019 22:28:08 +0000 Subject: [PATCH] move proto/pingping to discovery module This is needed for the new peer discovery enabled by libp2p Signed-off-by: Leo Chen --- api/proto/common.go | 13 ++-- api/proto/{node => discovery}/pingpong.go | 61 ++++--------------- .../{node => discovery}/pingpong_test.go | 5 +- api/proto/node/node.go | 42 +++++++++++-- consensus/consensus.go | 4 +- node/node.go | 3 +- node/node_handler.go | 7 ++- node/node_test.go | 6 +- 8 files changed, 72 insertions(+), 69 deletions(-) rename api/proto/{node => discovery}/pingpong.go (76%) rename api/proto/{node => discovery}/pingpong_test.go (96%) diff --git a/api/proto/common.go b/api/proto/common.go index cda045114..94c921e87 100644 --- a/api/proto/common.go +++ b/api/proto/common.go @@ -34,11 +34,14 @@ const ( // TODO: add more types ) -// MessageCategoryBytes is the number of bytes message category takes -const MessageCategoryBytes = 1 - -// MessageTypeBytes is the number of bytes message type takes -const MessageTypeBytes = 1 +const ( + // ProtocolVersion is a constant defined as the version of the Harmony protocol + ProtocolVersion = 1 + // MessageCategoryBytes is the number of bytes message category takes + MessageCategoryBytes = 1 + // MessageTypeBytes is the number of bytes message type takes + MessageTypeBytes = 1 +) // GetMessageCategory gets the message category from the p2p message content func GetMessageCategory(message []byte) (MessageCategory, error) { diff --git a/api/proto/node/pingpong.go b/api/proto/discovery/pingpong.go similarity index 76% rename from api/proto/node/pingpong.go rename to api/proto/discovery/pingpong.go index 9f340270f..9c645bf8d 100644 --- a/api/proto/node/pingpong.go +++ b/api/proto/discovery/pingpong.go @@ -1,5 +1,5 @@ /* -Package proto/node implements the communication protocol among nodes. +Package proto/discovery implements the discovery ping/pong protocol among nodes. pingpong.go adds support of ping/pong messages. @@ -8,7 +8,7 @@ pong: peer responds to ping messages, sending all pubkeys known by peer */ -package node +package discovery import ( "bytes" @@ -18,55 +18,20 @@ import ( "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/api/proto" + "github.com/harmony-one/harmony/api/proto/node" "github.com/harmony-one/harmony/p2p" - peer "github.com/libp2p/go-libp2p-peer" ) -// RoleType defines the role of the node -type RoleType int - -// Type of roles of a node -const ( - ValidatorRole RoleType = iota - ClientRole -) - -func (r RoleType) String() string { - switch r { - case ValidatorRole: - return "Validator" - case ClientRole: - return "Client" - } - return "Unknown" -} - -// Info refers to Peer struct in p2p/peer.go -// this is basically a simplified version of Peer -// for network transportation -type Info struct { - IP string - Port string - PubKey []byte - ValidatorID int - Role RoleType - PeerID peer.ID // Peerstore ID -} - -func (info Info) String() string { - return fmt.Sprintf("Info:%v/%v=>%v/%v", info.IP, info.Port, info.ValidatorID, info.PeerID) -} - // PingMessageType defines the data structure of the Ping message type PingMessageType struct { Version uint16 // version of the protocol - Node Info + Node node.Info } // PongMessageType defines the data structure of the Pong message type PongMessageType struct { Version uint16 // version of the protocol - Peers []Info + Peers []node.Info PubKeys [][]byte // list of publickKeys, has to be identical among all validators/leaders } @@ -83,13 +48,13 @@ func (p PongMessageType) String() string { func NewPingMessage(peer p2p.Peer) *PingMessageType { ping := new(PingMessageType) - ping.Version = ProtocolVersion + ping.Version = proto.ProtocolVersion ping.Node.IP = peer.IP ping.Node.Port = peer.Port ping.Node.PeerID = peer.PeerID ping.Node.ValidatorID = peer.ValidatorID ping.Node.PubKey = peer.PubKey.Serialize() - ping.Node.Role = ValidatorRole + ping.Node.Role = node.ValidatorRole return ping } @@ -99,12 +64,12 @@ func NewPongMessage(peers []p2p.Peer, pubKeys []*bls.PublicKey) *PongMessageType pong := new(PongMessageType) pong.PubKeys = make([][]byte, 0) - pong.Version = ProtocolVersion - pong.Peers = make([]Info, 0) + pong.Version = proto.ProtocolVersion + pong.Peers = make([]node.Info, 0) var err error for _, p := range peers { - n := Info{} + n := node.Info{} n.IP = p.IP n.Port = p.Port n.ValidatorID = p.ValidatorID @@ -144,7 +109,7 @@ func GetPingMessage(payload []byte) (*PingMessageType, error) { // GetPongMessage deserializes the Pong Message from a list of byte func GetPongMessage(payload []byte) (*PongMessageType, error) { pong := new(PongMessageType) - pong.Peers = make([]Info, 0) + pong.Peers = make([]node.Info, 0) pong.PubKeys = make([][]byte, 0) r := bytes.NewBuffer(payload) @@ -161,7 +126,7 @@ func GetPongMessage(payload []byte) (*PongMessageType, error) { // ConstructPingMessage contructs ping message from node to leader func (p PingMessageType) ConstructPingMessage() []byte { byteBuffer := bytes.NewBuffer([]byte{byte(proto.Node)}) - byteBuffer.WriteByte(byte(PING)) + byteBuffer.WriteByte(byte(node.PING)) encoder := gob.NewEncoder(byteBuffer) err := encoder.Encode(p) @@ -175,7 +140,7 @@ func (p PingMessageType) ConstructPingMessage() []byte { // ConstructPongMessage contructs pong message from leader to node func (p PongMessageType) ConstructPongMessage() []byte { byteBuffer := bytes.NewBuffer([]byte{byte(proto.Node)}) - byteBuffer.WriteByte(byte(PONG)) + byteBuffer.WriteByte(byte(node.PONG)) encoder := gob.NewEncoder(byteBuffer) err := encoder.Encode(p) diff --git a/api/proto/node/pingpong_test.go b/api/proto/discovery/pingpong_test.go similarity index 96% rename from api/proto/node/pingpong_test.go rename to api/proto/discovery/pingpong_test.go index cf3b629a6..61dea2d73 100644 --- a/api/proto/node/pingpong_test.go +++ b/api/proto/discovery/pingpong_test.go @@ -1,4 +1,4 @@ -package node +package discovery import ( "fmt" @@ -8,6 +8,7 @@ import ( "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/api/proto" + "github.com/harmony-one/harmony/api/proto/node" "github.com/harmony-one/harmony/crypto/pki" "github.com/harmony-one/harmony/p2p" ) @@ -55,7 +56,7 @@ func TestString(test *testing.T) { test.Errorf("expect: %v, got: %v", e1, r1) } - ping1.Node.Role = ClientRole + ping1.Node.Role = node.ClientRole r3 := fmt.Sprintf("%v", *ping1) if strings.Compare(r3, e3) != 0 { diff --git a/api/proto/node/node.go b/api/proto/node/node.go index 2c7b34120..ee46f888c 100644 --- a/api/proto/node/node.go +++ b/api/proto/node/node.go @@ -3,6 +3,7 @@ package node import ( "bytes" "encoding/gob" + "fmt" "log" "github.com/ethereum/go-ethereum/common" @@ -10,16 +11,12 @@ import ( "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/api/proto" + peer "github.com/libp2p/go-libp2p-peer" ) // MessageType is to indicate the specific type of message under Node category type MessageType byte -// ProtocolVersion is a constant defined as the version of the Harmony protocol -const ( - ProtocolVersion = 1 -) - // Constant of the top level Message Type exchanged among nodes const ( Transaction MessageType = iota @@ -57,6 +54,41 @@ const ( Unlock ) +// RoleType defines the role of the node +type RoleType int + +// Type of roles of a node +const ( + ValidatorRole RoleType = iota + ClientRole +) + +func (r RoleType) String() string { + switch r { + case ValidatorRole: + return "Validator" + case ClientRole: + return "Client" + } + return "Unknown" +} + +// Info refers to Peer struct in p2p/peer.go +// this is basically a simplified version of Peer +// for network transportation +type Info struct { + IP string + Port string + PubKey []byte + ValidatorID int + Role RoleType + PeerID peer.ID // Peerstore ID +} + +func (info Info) String() string { + return fmt.Sprintf("Info:%v/%v=>%v/%v", info.IP, info.Port, info.ValidatorID, info.PeerID) +} + // BlockMessageType represents the type of messages used for Node/Block type BlockMessageType int diff --git a/consensus/consensus.go b/consensus/consensus.go index 0fc207191..0d36401c0 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -26,7 +26,7 @@ import ( "github.com/harmony-one/harmony/p2p/host" "golang.org/x/crypto/sha3" - proto_node "github.com/harmony-one/harmony/api/proto/node" + proto_discovery "github.com/harmony-one/harmony/api/proto/discovery" ) // Consensus is the main struct with all states and data related to consensus process. @@ -412,7 +412,7 @@ func (consensus *Consensus) RemovePeers(peers []p2p.Peer) int { // Or the shard won't be able to reach consensus if public keys are mismatch validators := consensus.GetValidatorPeers() - pong := proto_node.NewPongMessage(validators, consensus.PublicKeys) + pong := proto_discovery.NewPongMessage(validators, consensus.PublicKeys) buffer := pong.ConstructPongMessage() host.BroadcastMessageFromLeader(consensus.host, validators, buffer, consensus.OfflinePeers) diff --git a/node/node.go b/node/node.go index a01ba8c5a..6abb31507 100644 --- a/node/node.go +++ b/node/node.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/harmony-one/harmony/api/client" clientService "github.com/harmony-one/harmony/api/client/service" + proto_discovery "github.com/harmony-one/harmony/api/proto/discovery" proto_node "github.com/harmony-one/harmony/api/proto/node" "github.com/harmony-one/harmony/api/services/explorer" "github.com/harmony-one/harmony/api/services/syncing" @@ -432,7 +433,7 @@ func (node *Node) JoinShard(leader p2p.Peer) { for { select { case <-tick.C: - ping := proto_node.NewPingMessage(node.SelfPeer) + ping := proto_discovery.NewPingMessage(node.SelfPeer) if node.Client != nil { // assume this is the client node ping.Node.Role = proto_node.ClientRole } diff --git a/node/node_handler.go b/node/node_handler.go index 085b379fa..b1e52d762 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/api/proto" + proto_discovery "github.com/harmony-one/harmony/api/proto/discovery" proto_identity "github.com/harmony-one/harmony/api/proto/identity" proto_node "github.com/harmony-one/harmony/api/proto/node" "github.com/harmony-one/harmony/core/types" @@ -288,7 +289,7 @@ func (node *Node) AddNewBlock(newBlock *types.Block) { } func (node *Node) pingMessageHandler(msgPayload []byte) int { - ping, err := proto_node.GetPingMessage(msgPayload) + ping, err := proto_discovery.GetPingMessage(msgPayload) if err != nil { utils.GetLogInstance().Error("Can't get Ping Message") return -1 @@ -318,7 +319,7 @@ func (node *Node) pingMessageHandler(msgPayload []byte) int { node.AddPeers([]*p2p.Peer{peer}) peers := node.Consensus.GetValidatorPeers() - pong := proto_node.NewPongMessage(peers, node.Consensus.PublicKeys) + pong := proto_discovery.NewPongMessage(peers, node.Consensus.PublicKeys) buffer := pong.ConstructPongMessage() // Send a Pong message directly to the sender @@ -339,7 +340,7 @@ func (node *Node) pingMessageHandler(msgPayload []byte) int { } func (node *Node) pongMessageHandler(msgPayload []byte) int { - pong, err := proto_node.GetPongMessage(msgPayload) + pong, err := proto_discovery.GetPongMessage(msgPayload) if err != nil { utils.GetLogInstance().Error("Can't get Pong Message") return -1 diff --git a/node/node_test.go b/node/node_test.go index 538a0833f..26a08cb3d 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - proto_node "github.com/harmony-one/harmony/api/proto/node" + proto_discovery "github.com/harmony-one/harmony/api/proto/discovery" "github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/crypto/pki" "github.com/harmony-one/harmony/internal/utils" @@ -114,7 +114,7 @@ func sendPingMessage(node *Node, leader p2p.Peer) { PubKey: pubKey1, } - ping1 := proto_node.NewPingMessage(p1) + ping1 := proto_discovery.NewPingMessage(p1) buf1 := ping1.ConstructPingMessage() fmt.Println("waiting for 5 seconds ...") @@ -138,7 +138,7 @@ func sendPongMessage(node *Node, leader p2p.Peer) { PubKey: pubKey2, } - pong1 := proto_node.NewPongMessage([]p2p.Peer{p1, p2}, nil) + pong1 := proto_discovery.NewPongMessage([]p2p.Peer{p1, p2}, nil) buf1 := pong1.ConstructPongMessage() fmt.Println("waiting for 10 seconds ...")