github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/raft/peer.go (about) 1 package raft 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "net" 8 9 "github.com/kisexp/xdchain/p2p/enode" 10 "github.com/kisexp/xdchain/p2p/enr" 11 "github.com/kisexp/xdchain/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 NodeActive bool `json:"nodeActive"` 34 } 35 36 func newAddress(raftId uint16, raftPort int, node *enode.Node, useDns bool) *Address { 37 // derive 64 byte nodeID from 128 byte enodeID 38 id, err := enode.RaftHexID(node.EnodeID()) 39 if err != nil { 40 panic(err) 41 } 42 if useDns && node.Host() != "" { 43 return &Address{ 44 RaftId: raftId, 45 NodeId: id, 46 Ip: nil, 47 P2pPort: enr.TCP(node.TCP()), 48 RaftPort: enr.RaftPort(raftPort), 49 Hostname: node.Host(), 50 } 51 } 52 return &Address{ 53 RaftId: raftId, 54 NodeId: id, 55 Ip: nil, 56 P2pPort: enr.TCP(node.TCP()), 57 RaftPort: enr.RaftPort(raftPort), 58 Hostname: node.IP().String(), 59 } 60 } 61 62 // A peer that we're connected to via both raft's http transport, and ethereum p2p 63 type Peer struct { 64 address *Address // For raft transport 65 p2pNode *enode.Node // For ethereum transport 66 } 67 68 // RLP Address encoding, for transport over raft and storage in LevelDB. 69 func (addr *Address) toBytes() []byte { 70 var toEncode interface{} 71 72 // need to check if addr.Hostname is hostname/ip 73 if ip := net.ParseIP(addr.Hostname); ip == nil { 74 toEncode = addr 75 } else { 76 toEncode = []interface{}{addr.RaftId, addr.NodeId, ip, addr.P2pPort, addr.RaftPort} 77 } 78 79 buffer, err := rlp.EncodeToBytes(toEncode) 80 if err != nil { 81 panic(fmt.Sprintf("error: failed to RLP-encode Address: %s", err.Error())) 82 } 83 return buffer 84 } 85 86 func bytesToAddress(input []byte) *Address { 87 // try the new format first 88 addr := new(Address) 89 streamNew := rlp.NewStream(bytes.NewReader(input), 0) 90 if err := streamNew.Decode(addr); err == nil { 91 return addr 92 } 93 94 // else try the old format 95 var temp struct { 96 RaftId uint16 97 NodeId enode.EnodeID 98 Ip net.IP 99 P2pPort enr.TCP 100 RaftPort enr.RaftPort 101 } 102 103 streamOld := rlp.NewStream(bytes.NewReader(input), 0) 104 if err := streamOld.Decode(&temp); err != nil { 105 log.Fatalf("failed to RLP-decode Address: %v", err) 106 } 107 108 return &Address{ 109 RaftId: temp.RaftId, 110 NodeId: temp.NodeId, 111 Ip: nil, 112 P2pPort: temp.P2pPort, 113 RaftPort: temp.RaftPort, 114 Hostname: temp.Ip.String(), 115 } 116 }