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  }