arnaucube
arnaucube/blockchainIDsystemPublic Self-hosted repository
blockchainIDsystem/peer/peers.go
peer/peers.goRaw
  1package main
  2
  3import (
  4	"fmt"
  5	"net"
  6	"time"
  7
  8	"github.com/fatih/color"
  9)
 10
 11type PeersList struct {
 12	PeerID string
 13	Peers  []Peer    `json:"peerslist"`
 14	Date   time.Time `json:"date"`
 15}
 16
 17var outcomingPeersList PeersList
 18var incomingPeersList PeersList
 19var networkPeersList PeersList //the peers that have been received in the lists from other peers
 20
 21/*
 22a future option is to put:
 23	type PeersList struct {
 24		Incoming	PeersList
 25		Outcoming	PeersList
 26		Network	PeersList
 27	}
 28*/
 29
 30func peerIsInPeersList(p Peer, pl []Peer) int {
 31	r := -1
 32	for i, peer := range pl {
 33		if peer.IP+":"+peer.Port == p.IP+":"+p.Port {
 34			r = i
 35		}
 36	}
 37	return r
 38}
 39
 40func deletePeerFromPeersList(p Peer, pl *PeersList) {
 41	i := peerIsInPeersList(p, pl.Peers)
 42	if i != -1 {
 43		//delete peer from pl.Peers
 44		pl.Peers = append(pl.Peers[:i], pl.Peers[i+1:]...)
 45	}
 46}
 47func appendPeerIfNoExist(pl PeersList, p Peer) PeersList {
 48	i := peerIsInPeersList(p, pl.Peers)
 49	if i == -1 {
 50		pl.Peers = append(pl.Peers, p)
 51	}
 52	return pl
 53}
 54func updateNetworkPeersList(conn net.Conn, newPeersList PeersList) {
 55	for _, peer := range newPeersList.Peers {
 56		if getIPPortFromConn(conn) == peer.IP+":"+peer.Port {
 57			peer.ID = newPeersList.PeerID
 58			color.Yellow(peer.ID)
 59		}
 60		i := peerIsInPeersList(peer, networkPeersList.Peers)
 61		if i == -1 {
 62			networkPeersList.Peers = append(networkPeersList.Peers, peer)
 63		} else {
 64			fmt.Println(networkPeersList.Peers[i])
 65			networkPeersList.Peers[i].ID = peer.ID
 66		}
 67	}
 68}
 69func searchPeerAndUpdate(p Peer) {
 70	for _, peer := range outcomingPeersList.Peers {
 71		color.Red(p.IP + ":" + p.Port)
 72		color.Yellow(peer.IP + ":" + peer.Port)
 73		if p.IP+":"+p.Port == peer.IP+":"+peer.Port {
 74			peer.ID = p.ID
 75		}
 76	}
 77}
 78
 79//send the outcomingPeersList to all the peers except the peer p that has send the outcomingPeersList
 80func propagatePeersList(p Peer) {
 81	for _, peer := range networkPeersList.Peers {
 82		if peer.Conn != nil {
 83			if peer.ID != p.ID && p.ID != "" {
 84				color.Yellow(peer.ID + " - " + p.ID)
 85				var msg Msg
 86				msg.construct("PeersList", "here my outcomingPeersList")
 87				msg.PeersList = outcomingPeersList
 88				msgB := msg.toBytes()
 89				_, err := peer.Conn.Write(msgB)
 90				check(err)
 91			} else {
 92				/*
 93					for the moment, this is not being called, due that in the IncomingPeersList,
 94					there is no peer.ID, so in the comparation wih the peer that has send the
 95					peersList, is comparing ID with "", so nevere enters this 'else' section
 96
 97					maybe it's not needed. TODO check if it's needed the PeerList_Response
 98					For the moment is working without it
 99				*/
100				//to the peer that has sent the peerList, we send our PeersList
101
102				var msg Msg
103				msg.construct("PeersList_Response", "here my outcomingPeersList")
104				msg.PeersList = outcomingPeersList
105				msgB := msg.toBytes()
106				_, err := peer.Conn.Write(msgB)
107				check(err)
108			}
109		} else {
110			//connect to peer
111			if peer.ID != p.ID && peer.ID != runningPeer.ID {
112				if peerIsInPeersList(peer, outcomingPeersList.Peers) == -1 {
113					color.Red("no connection, connecting to peer: " + peer.Port)
114					connectToPeer(peer)
115				}
116			}
117
118		}
119	}
120}
121func printPeersList() {
122	fmt.Println("")
123	color.Blue("runningPeer.ID: " + runningPeer.ID)
124	color.Green("OUTCOMING PEERSLIST:")
125	for _, peer := range outcomingPeersList.Peers {
126		fmt.Println(peer)
127	}
128	color.Green("INCOMING PEERSLIST:")
129	for _, peer := range incomingPeersList.Peers {
130		fmt.Println(peer)
131	}
132
133	color.Green("NETWORK PEERSLIST:")
134	for _, peer := range networkPeersList.Peers {
135		fmt.Println(peer)
136	}
137	fmt.Println("")
138}
139
140//send the block to all the peers of the outcomingPeersList
141func propagateBlock(b Block) {
142	//prepare the msg to send to all connected peers
143	var msg Msg
144	msg.construct("Block", "new block")
145	msg.Block = b
146	msgB := msg.toBytes()
147	for _, peer := range outcomingPeersList.Peers {
148		if peer.Conn != nil {
149			_, err := peer.Conn.Write(msgB)
150			check(err)
151		}
152	}
153}