git.gammaspectra.live/P2Pool/consensus/v3@v3.8.0/monero/client/levin/node.go (about) 1 package levin 2 3 import ( 4 "fmt" 5 "net" 6 ) 7 8 type Node struct { 9 Peers map[string]*Peer 10 11 Id uint64 12 RPCPort uint16 13 14 CurrentHeight uint64 15 TopVersion uint8 16 } 17 18 func (l *Node) GetPeers() map[string]*Peer { 19 return l.Peers 20 } 21 22 type Peer struct { 23 Ip string 24 Port uint16 25 } 26 27 func (p Peer) Addr() string { 28 return fmt.Sprintf("%s:%d", p.Ip, p.Port) 29 } 30 31 func (p Peer) String() string { 32 return p.Addr() 33 } 34 35 func ParsePeerList(entry Entry) map[string]*Peer { 36 peers := map[string]*Peer{} 37 38 peerList := entry.Entries() 39 40 for _, peer := range peerList { 41 peerListAdr := peer.Entries() 42 43 for _, adr := range peerListAdr { 44 if adr.Name != "adr" { 45 continue 46 } 47 48 addr := adr.Entries() 49 50 for _, addrField := range addr { 51 if addrField.Name != "addr" { 52 continue 53 } 54 55 fields := addrField.Entries() 56 57 var ip string 58 var port uint16 59 60 for _, field := range fields { 61 if field.Name == "m_ip" { 62 ip = ipzify(field.Uint32()) 63 } 64 65 if field.Name == "m_port" { 66 port = field.Uint16() 67 } 68 69 if field.Name == "addr" { 70 ip = net.IP([]byte(field.String())).String() 71 } 72 } 73 74 if ip != "" && port != 0 { 75 peer := &Peer{ 76 Ip: ip, 77 Port: port, 78 } 79 80 peers[peer.Addr()] = peer 81 } 82 } 83 } 84 } 85 86 return peers 87 } 88 89 // TODO less panic'ing. 90 func NewNodeFromEntries(entries Entries) Node { 91 lpl := Node{} 92 93 for _, entry := range entries { 94 if entry.Name == "node_data" { 95 for _, field := range entry.Entries() { 96 switch field.Name { 97 case "rpc_port": 98 lpl.RPCPort = field.Uint16() 99 case "peer_id": 100 lpl.Id = field.Uint64() 101 } 102 } 103 } 104 105 if entry.Name == "payload_data" { 106 for _, field := range entry.Entries() { 107 switch field.Name { 108 case "current_height": 109 lpl.CurrentHeight = field.Uint64() 110 case "top_version": 111 lpl.TopVersion = field.Uint8() 112 } 113 } 114 } 115 116 if entry.Name == "local_peerlist_new" { 117 lpl.Peers = ParsePeerList(entry) 118 } 119 } 120 121 return lpl 122 } 123 124 func ipzify(ip uint32) string { 125 result := make(net.IP, 4) 126 127 result[0] = byte(ip) 128 result[1] = byte(ip >> 8) 129 result[2] = byte(ip >> 16) 130 result[3] = byte(ip >> 24) 131 132 return result.String() 133 }