diff --git a/README.md b/README.md index 078f8fc..03082cb 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # bc Own p2p network and own blockchain libraries written in Go, to develop own decentralized apps. + +The purpose of this code is to learn to develop a p2p network and a blockchain system. diff --git a/peer/main.go b/peer/main.go index 9f462a0..0b34144 100644 --- a/peer/main.go +++ b/peer/main.go @@ -30,8 +30,10 @@ func main() { check(err) blockchain.Print() + //initialize p2plib + configuredMsgCases := createMsgHandlerCases() tp = p2plib.InitializePeer(os.Args[1], "127.0.0.1", - os.Args[2], os.Args[3], config.ServerIP, config.ServerPort) + os.Args[2], os.Args[3], config.ServerIP, config.ServerPort, configuredMsgCases) if tp.RunningPeer.Role == "client" { color.Red("http://" + config.IP + ":" + config.ServerRESTPort) diff --git a/peer/messageHandler.go b/peer/messageHandler.go new file mode 100644 index 0000000..9c2bdec --- /dev/null +++ b/peer/messageHandler.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + + p2plib "./p2plib" + + blockchainlib "./blockchainlib" +) + +func createMsgHandlerCases() map[string]func(p2plib.Peer, p2plib.Msg) { + configuredMsgCases := make(map[string]func(p2plib.Peer, p2plib.Msg)) + configuredMsgCases["Block"] = func(peer p2plib.Peer, msg p2plib.Msg) { + //TODO check if the block is signed by an autorized emitter + //block = msg.Data converted to Block + var block blockchainlib.Block + if !blockchain.BlockExists(block) { + blockchain.AddBlock(block) + p2plib.PropagateData(peer, "block in string format") + } + } + + fmt.Println(configuredMsgCases) + return configuredMsgCases +} diff --git a/peer/p2plib/init.go b/peer/p2plib/init.go index 7e66149..15c04cb 100644 --- a/peer/p2plib/init.go +++ b/peer/p2plib/init.go @@ -4,12 +4,17 @@ import ( "fmt" "math/rand" "time" + + "github.com/fatih/color" ) -func InitializePeer(role, ip, port, restport, serverip, serverport string) ThisPeer { +func InitializePeer(role, ip, port, restport, serverip, serverport string, + configuredMsgCases map[string]func(Peer, Msg)) ThisPeer { //initialize some vars rand.Seed(time.Now().Unix()) + InitializeDefaultMsgCases(configuredMsgCases) + var tp ThisPeer tp.Running = true tp.RunningPeer.Role = role @@ -41,3 +46,35 @@ func InitializePeer(role, ip, port, restport, serverip, serverport string) ThisP return tp } + +func InitializeDefaultMsgCases(configuredMsgCases map[string]func(Peer, Msg)) { + //msgCases := make(map[string]func(Peer, Msg)) --> no, it's used the global + msgCases = make(map[string]func(Peer, Msg)) + + //get the user configured msgCases + for k, v := range configuredMsgCases { + msgCases[k] = v + } + + msgCases["Hi"] = func(peer Peer, msg Msg) { + color.Yellow(msg.Type) + color.Green(msg.Content) + } + + msgCases["PeersList"] = func(peer Peer, msg Msg) { + color.Blue("newPeerslist") + fmt.Println(msg.PeersList) + color.Red("PeersList") + + UpdateNetworkPeersList(peer.Conn, msg.PeersList) + PropagatePeersList(peer) + PrintPeersList() + } + + msgCases["Data"] = func(peer Peer, msg Msg) { + color.Yellow(msg.Type) + color.Green(msg.Content) + PropagateData(peer, "data") + } + fmt.Println(msgCases) +} diff --git a/peer/p2plib/messages.go b/peer/p2plib/messages.go index 3a8e507..be8f40a 100644 --- a/peer/p2plib/messages.go +++ b/peer/p2plib/messages.go @@ -2,11 +2,8 @@ package p2plib import ( "encoding/json" - "fmt" "log" "time" - - "github.com/fatih/color" ) type Msg struct { @@ -17,46 +14,24 @@ type Msg struct { Data []byte `json:"data"` } +type Case struct { + Case string + Function func(Peer, Msg) +} + +var msgCases map[string]func(Peer, Msg) + func MessageHandler(peer Peer, msg Msg) { log.Println("[New msg]") log.Println(msg) - switch msg.Type { - case "Hi": - color.Yellow(msg.Type) - color.Green(msg.Content) - break - case "PeersList": - color.Blue("newPeerslist") - fmt.Println(msg.PeersList) - color.Red("PeersList") - - UpdateNetworkPeersList(peer.Conn, msg.PeersList) - PropagatePeersList(peer) - PrintPeersList() - break - case "PeersList_Response": - //for the moment is not beeing used - color.Blue("newPeerslist, from PeersList_Response") - fmt.Println(msg.PeersList) - color.Red("PeersList_Response") - - UpdateNetworkPeersList(peer.Conn, msg.PeersList) - PropagatePeersList(peer) - PrintPeersList() - break - case "Block": - /*//TODO check if the block is signed by an autorized emitter - if !blockchain.blockExists(msg.Block) { - blockchain.addBlock(msg.Block) - propagateBlock(msg.Block) - }*/ - break - default: - log.Println("Msg.Type not supported") - break - } + /*for c, caseFunction := range msgCases { + if msg.Type == c { + caseFunction(peer, msg) + } + }*/ + msgCases[msg.Type](peer, msg) } func (msg *Msg) Construct(msgtype string, msgcontent string) { diff --git a/peer/p2plib/peers.go b/peer/p2plib/peers.go index a67e7c1..db623b6 100644 --- a/peer/p2plib/peers.go +++ b/peer/p2plib/peers.go @@ -147,6 +147,21 @@ func PrintPeersList() { } fmt.Println("") } +func PropagateData(p Peer, s string) { + //prepare the msg to send to all connected peers + var msg Msg + msg.Construct("Data", "new Data") + msg.Data = []byte(s) + msgB := msg.ToBytes() + for _, peer := range globalTP.PeersConnections.Outcoming.Peers { + if peer.Conn != nil { + if peer.ID != p.ID && p.ID != "" { + _, err := peer.Conn.Write(msgB) + check(err) + } + } + } +} //send the block to all the peers of the outcomingPeersList /*func PropagateBlock(b Block) { diff --git a/peer/p2plib/petitions.go b/peer/p2plib/petitions.go new file mode 100644 index 0000000..c0e4f49 --- /dev/null +++ b/peer/p2plib/petitions.go @@ -0,0 +1,6 @@ +package p2plib + +func SendPetition(peer Peer, petition string) { + _, err := peer.Conn.Write([]byte(petition)) + check(err) +}