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}
150
151//send the block to all the peers of the outcomingPeersList
152/*func PropagateBlock(b Block) {
153	//prepare the msg to send to all connected peers
154	var msg Msg
155	msg.construct("Block", "new block")
156	msg.Block = b
157	msgB := msg.toBytes()
158	for _, peer := range outcomingPeersList.Peers {
159		if peer.Conn != nil {
160			_, err := peer.Conn.Write(msgB)
161			check(err)
162		}
163	}
164}*/