github.com/hyperion-hyn/go-ethereum@v2.4.0+incompatible/raft/peer.go (about) 1 package raft 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "net" 8 9 "github.com/ethereum/go-ethereum/p2p/enode" 10 "github.com/ethereum/go-ethereum/p2p/enr" 11 "github.com/ethereum/go-ethereum/rlp" 12 ) 13 14 // Serializable information about a Peer. Sufficient to build `etcdRaft.Peer` 15 // or `enode.Node`. 16 // As NodeId is mainly used to derive the `ecdsa.pubkey` to build `enode.Node` it is kept as [64]byte instead of ID [32]byte used by `enode.Node`. 17 type Address struct { 18 RaftId uint16 `json:"raftId"` 19 NodeId enode.EnodeID `json:"nodeId"` 20 Ip net.IP `json:"-"` 21 P2pPort enr.TCP `json:"p2pPort"` 22 RaftPort enr.RaftPort `json:"raftPort"` 23 24 Hostname string `json:"hostname"` 25 26 // Ignore additional fields (for forward compatibility). 27 Rest []rlp.RawValue `json:"-" rlp:"tail"` 28 } 29 30 type ClusterInfo struct { 31 Address 32 Role string `json:"role"` 33 } 34 35 func newAddress(raftId uint16, raftPort int, node *enode.Node, withHostname bool) *Address { 36 // derive 64 byte nodeID from 128 byte enodeID 37 id, err := enode.RaftHexID(node.EnodeID()) 38 if err != nil { 39 panic(err) 40 } 41 if withHostname { 42 return &Address{ 43 RaftId: raftId, 44 NodeId: id, 45 Ip: nil, 46 P2pPort: enr.TCP(node.TCP()), 47 RaftPort: enr.RaftPort(raftPort), 48 Hostname: node.Host(), 49 } 50 } 51 return &Address{ 52 RaftId: raftId, 53 NodeId: id, 54 Ip: nil, 55 P2pPort: enr.TCP(node.TCP()), 56 RaftPort: enr.RaftPort(raftPort), 57 Hostname: node.IP().String(), 58 } 59 } 60 61 // A peer that we're connected to via both raft's http transport, and ethereum p2p 62 type Peer struct { 63 address *Address // For raft transport 64 p2pNode *enode.Node // For ethereum transport 65 } 66 67 // RLP Address encoding, for transport over raft and storage in LevelDB. 68 func (addr *Address) toBytes(withHostname bool) []byte { 69 var toEncode interface{} 70 71 if withHostname { 72 toEncode = addr 73 } else { 74 toEncode = []interface{}{addr.RaftId, addr.NodeId, net.ParseIP(addr.Hostname), addr.P2pPort, addr.RaftPort} 75 } 76 77 buffer, err := rlp.EncodeToBytes(toEncode) 78 if err != nil { 79 panic(fmt.Sprintf("error: failed to RLP-encode Address: %s", err.Error())) 80 } 81 return buffer 82 } 83 84 func bytesToAddress(input []byte) *Address { 85 //try the new format first 86 addr := new(Address) 87 streamNew := rlp.NewStream(bytes.NewReader(input), 0) 88 if err := streamNew.Decode(addr); err == nil { 89 return addr 90 } 91 92 //else try the old format 93 var temp struct { 94 RaftId uint16 95 NodeId enode.EnodeID 96 Ip net.IP 97 P2pPort enr.TCP 98 RaftPort enr.RaftPort 99 } 100 101 streamOld := rlp.NewStream(bytes.NewReader(input), 0) 102 if err := streamOld.Decode(&temp); err != nil { 103 log.Fatalf("failed to RLP-decode Address: %v", err) 104 } 105 106 return &Address{ 107 RaftId: temp.RaftId, 108 NodeId: temp.NodeId, 109 Ip: nil, 110 P2pPort: temp.P2pPort, 111 RaftPort: temp.RaftPort, 112 Hostname: temp.Ip.String(), 113 } 114 }