arnaucube
arnaucube/bcPublic Self-hosted repository
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}*/