bc/peer/p2plib/peers.go
peer/p2plib/peers.goRaw
1package p2plib
2
3import (
4 "fmt"
5 "net"
6 "time"
7
8 "github.com/fatih/color"
9)
10
11type Peer struct {
12 ID string `json:"id"` //in the future, this will be the peer hash
13 IP string `json:"ip"`
14 Port string `json:"port"`
15 RESTPort string `json:"restport"`
16 Role string `json:"role"` //client or server
17 Conn net.Conn `json:"conn"`
18}
19
20type PeersList struct {
21 PeerID string
22 Peers []Peer `json:"peerslist"`
23 Date time.Time `json:"date"`
24}
25
26type PeersConnections struct {
27 Incoming PeersList
28 Outcoming PeersList
29 Network PeersList //the peers that have been received in the lists from other peers
30}
31
32type ThisPeer struct {
33 Running bool
34 ID string
35 RunningPeer Peer
36 PeersConnections PeersConnections
37}
38
39var globalTP ThisPeer
40
41func PeerIsInPeersList(p Peer, pl []Peer) int {
42 r := -1
43 for i, peer := range pl {
44 if peer.IP+":"+peer.Port == p.IP+":"+p.Port {
45 r = i
46 }
47 }
48 return r
49}
50
51func DeletePeerFromPeersList(p Peer, pl *PeersList) {
52 i := PeerIsInPeersList(p, pl.Peers)
53 if i != -1 {
54 //delete peer from pl.Peers
55 pl.Peers = append(pl.Peers[:i], pl.Peers[i+1:]...)
56 }
57}
58func AppendPeerIfNoExist(pl PeersList, p Peer) PeersList {
59 i := PeerIsInPeersList(p, pl.Peers)
60 if i == -1 {
61 pl.Peers = append(pl.Peers, p)
62 }
63 return pl
64}
65func UpdateNetworkPeersList(conn net.Conn, newPeersList PeersList) {
66 for _, peer := range newPeersList.Peers {
67 if GetIPPortFromConn(conn) == peer.IP+":"+peer.Port {
68 peer.ID = newPeersList.PeerID
69 color.Yellow(peer.ID)
70 }
71 i := PeerIsInPeersList(peer, globalTP.PeersConnections.Network.Peers)
72 if i == -1 {
73 globalTP.PeersConnections.Network.Peers = append(globalTP.PeersConnections.Network.Peers, peer)
74 } else {
75 fmt.Println(globalTP.PeersConnections.Network.Peers[i])
76 globalTP.PeersConnections.Network.Peers[i].ID = peer.ID
77 }
78 }
79}
80func SearchPeerAndUpdate(p Peer) {
81 for _, peer := range globalTP.PeersConnections.Outcoming.Peers {
82 color.Red(p.IP + ":" + p.Port)
83 color.Yellow(peer.IP + ":" + peer.Port)
84 if p.IP+":"+p.Port == peer.IP+":"+peer.Port {
85 peer.ID = p.ID
86 }
87 }
88}
89
90//send the outcomingPeersList to all the peers except the peer p that has send the outcomingPeersList
91func PropagatePeersList(p Peer) {
92 for _, peer := range globalTP.PeersConnections.Network.Peers {
93 if peer.Conn != nil {
94 if peer.ID != p.ID && p.ID != "" {
95 color.Yellow(peer.ID + " - " + p.ID)
96 var msg Msg
97 msg.Construct("PeersList", "here my outcomingPeersList")
98 msg.PeersList = globalTP.PeersConnections.Outcoming
99 msgB := msg.ToBytes()
100 _, err := peer.Conn.Write(msgB)
101 check(err)
102 } else {
103 /*
104 for the moment, this is not being called, due that in the IncomingPeersList,
105 there is no peer.ID, so in the comparation wih the peer that has send the
106 peersList, is comparing ID with "", so nevere enters this 'else' section
107
108 maybe it's not needed. TODO check if it's needed the PeerList_Response
109 For the moment is working without it
110 */
111 //to the peer that has sent the peerList, we send our PeersList
112
113 var msg Msg
114 msg.Construct("PeersList_Response", "here my outcomingPeersList")
115 msg.PeersList = globalTP.PeersConnections.Outcoming
116 msgB := msg.ToBytes()
117 _, err := peer.Conn.Write(msgB)
118 check(err)
119 }
120 } else {
121 //connect to peer
122 if peer.ID != p.ID && peer.ID != globalTP.RunningPeer.ID {
123 if PeerIsInPeersList(peer, globalTP.PeersConnections.Outcoming.Peers) == -1 {
124 color.Red("no connection, connecting to peer: " + peer.Port)
125 ConnectToPeer(peer)
126 }
127 }
128
129 }
130 }
131}
132func PrintPeersList() {
133 fmt.Println("")
134 color.Blue("runningPeer.ID: " + globalTP.RunningPeer.ID)
135 color.Green("OUTCOMING PEERSLIST:")
136 for _, peer := range globalTP.PeersConnections.Outcoming.Peers {
137 fmt.Println(peer)
138 }
139 color.Green("INCOMING PEERSLIST:")
140 for _, peer := range globalTP.PeersConnections.Incoming.Peers {
141 fmt.Println(peer)
142 }
143
144 color.Green("NETWORK PEERSLIST:")
145 for _, peer := range globalTP.PeersConnections.Network.Peers {
146 fmt.Println(peer)
147 }
148 fmt.Println("")
149}
150func PropagateData(p Peer, s string) {
151 //prepare the msg to send to all connected peers
152 var msg Msg
153 msg.Construct("Data", "new Data")
154 msg.Data = []byte(s)
155 msgB := msg.ToBytes()
156 for _, peer := range globalTP.PeersConnections.Outcoming.Peers {
157 if peer.Conn != nil {
158 if peer.ID != p.ID && p.ID != "" {
159 _, err := peer.Conn.Write(msgB)
160 check(err)
161 }
162 }
163 }
164}
165
166//send the block to all the peers of the outcomingPeersList
167/*func PropagateBlock(b Block) {
168 //prepare the msg to send to all connected peers
169 var msg Msg
170 msg.construct("Block", "new block")
171 msg.Block = b
172 msgB := msg.toBytes()
173 for _, peer := range outcomingPeersList.Peers {
174 if peer.Conn != nil {
175 _, err := peer.Conn.Write(msgB)
176 check(err)
177 }
178 }
179}*/