diff --git a/examples/multipro/echo.go b/examples/multipro/echo.go index 60e83c50e13f4f6e7f11926ea3c1afe76fa36c63..158a54a81051864a8579469ad26b35df9d59ecca 100644 --- a/examples/multipro/echo.go +++ b/examples/multipro/echo.go @@ -6,7 +6,6 @@ import ( "fmt" "log" - host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host" inet "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net" uuid "github.com/google/uuid" @@ -20,20 +19,20 @@ const echoRequest = "/echo/echoreq/0.0.1" const echoResponse = "/echo/echoresp/0.0.1" type EchoProtocol struct { - host host.Host // local host + node *Node // local host requests map[string]*p2p.EchoRequest // used to access request data from response handlers done chan bool // only for demo purposes to hold main from terminating } -func NewEchoProtocol(host host.Host, done chan bool) *EchoProtocol { - e := EchoProtocol{host: host, requests: make(map[string]*p2p.EchoRequest), done: done} - host.SetStreamHandler(echoRequest, e.onEchoRequest) - host.SetStreamHandler(echoResponse, e.onEchoResponse) +func NewEchoProtocol(node *Node, done chan bool) *EchoProtocol { + e := EchoProtocol{node: node, requests: make(map[string]*p2p.EchoRequest), done: done} + node.SetStreamHandler(echoRequest, e.onEchoRequest) + node.SetStreamHandler(echoResponse, e.onEchoResponse) return &e } // remote peer requests handler -func (e *EchoProtocol) onEchoRequest(s inet.Stream) { +func (e EchoProtocol) onEchoRequest(s inet.Stream) { // get request data data := &p2p.EchoRequest{} decoder := protobufCodec.Multicodec(nil).Decoder(bufio.NewReader(s)) @@ -49,10 +48,10 @@ func (e *EchoProtocol) onEchoRequest(s inet.Stream) { // send response to request send using the message string he provided resp := &p2p.EchoResponse{ - MessageData: NewMessageData(e.host.ID().String(), data.MessageData.Id, false), + MessageData: NewMessageData(e.node.ID().String(), data.MessageData.Id, false), Message: data.Message} - s, respErr := e.host.NewStream(context.Background(), s.Conn().RemotePeer(), echoResponse) + s, respErr := e.node.NewStream(context.Background(), s.Conn().RemotePeer(), echoResponse) if respErr != nil { log.Fatal(respErr) return @@ -66,7 +65,7 @@ func (e *EchoProtocol) onEchoRequest(s inet.Stream) { } // remote echo response handler -func (e *EchoProtocol) onEchoResponse(s inet.Stream) { +func (e EchoProtocol) onEchoResponse(s inet.Stream) { data := &p2p.EchoResponse{} decoder := protobufCodec.Multicodec(nil).Decoder(bufio.NewReader(s)) err := decoder.Decode(data) @@ -90,15 +89,15 @@ func (e *EchoProtocol) onEchoResponse(s inet.Stream) { e.done <- true } -func (e *EchoProtocol) Echo(node *Node) bool { - log.Printf("%s: Sending echo to: %s....", e.host.ID(), node.host.ID()) +func (e EchoProtocol) Echo(node *Node) bool { + log.Printf("%s: Sending echo to: %s....", e.node.ID(), node.ID()) // create message data req := &p2p.EchoRequest{ - MessageData: NewMessageData(e.host.ID().String(), uuid.New().String(), false), - Message: fmt.Sprintf("Echo from %s", e.host.ID())} + MessageData: NewMessageData(e.node.ID().String(), uuid.New().String(), false), + Message: fmt.Sprintf("Echo from %s", e.node.ID())} - s, err := e.host.NewStream(context.Background(), node.host.ID(), echoRequest) + s, err := e.node.NewStream(context.Background(), node.ID(), echoRequest) if err != nil { log.Fatal(err) return false @@ -112,6 +111,6 @@ func (e *EchoProtocol) Echo(node *Node) bool { // store request so response handler has access to it e.requests[req.MessageData.Id] = req - log.Printf("%s: Echo to: %s was sent. Message Id: %s, Message: %s", e.host.ID(), node.host.ID(), req.MessageData.Id, req.Message) + log.Printf("%s: Echo to: %s was sent. Message Id: %s, Message: %s", e.node.ID(), node.ID(), req.MessageData.Id, req.Message) return true } diff --git a/examples/multipro/main.go b/examples/multipro/main.go index 97218255da00eb9bd02760a7e3f88178ac3aa4dd..d6f7a1aaa4094f3c884ff2f3bfccb004ecdc84a0 100644 --- a/examples/multipro/main.go +++ b/examples/multipro/main.go @@ -41,10 +41,10 @@ func main() { // Make 2 hosts h1 := makeRandomNode(port1, done) h2 := makeRandomNode(port2, done) - h1.host.Peerstore().AddAddrs(h2.host.ID(), h2.host.Addrs(), ps.PermanentAddrTTL) - h2.host.Peerstore().AddAddrs(h1.host.ID(), h1.host.Addrs(), ps.PermanentAddrTTL) + h1.Peerstore().AddAddrs(h2.ID(), h2.Addrs(), ps.PermanentAddrTTL) + h2.Peerstore().AddAddrs(h1.ID(), h1.Addrs(), ps.PermanentAddrTTL) - log.Printf("This is a conversation between %s and %s\n", h1.host.ID(), h2.host.ID()) + log.Printf("This is a conversation between %s and %s\n", h1.ID(), h2.ID()) // send messages using the protocols h1.Ping(h2) diff --git a/examples/multipro/node.go b/examples/multipro/node.go index 0650b3ba278a822ad62c408bcc397e5514185fc3..0a10d5740408cf80f95ab2c0888b8138921ebd5c 100644 --- a/examples/multipro/node.go +++ b/examples/multipro/node.go @@ -1,57 +1,33 @@ package main import ( - "bufio" - "log" - "time" - host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host" - inet "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net" - - protobufCodec "github.com/multiformats/go-multicodec/protobuf" - - p2p "github.com/libp2p/go-libp2p/examples/multipro/pb" + peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer" ) -// node version -const clientVersion = "go-p2p-node/0.0.1" - -// helper method - writes a protobuf go data object to a network stream -// data - reference of protobuf go data object to send (not the object itself) -// s - network stream to write the data to -func sendDataObject(data interface{}, s inet.Stream) bool { - writer := bufio.NewWriter(s) - enc := protobufCodec.Multicodec(nil).Encoder(writer) - err := enc.Encode(data) - if err != nil { - log.Fatal(err) - return false - } - writer.Flush() - return true +func (n Node) signData(data []byte) ([]byte, error) { + key := n.Peerstore().PrivKey(n.ID()) + res, err := key.Sign(data) + return res, err } -// helper method - generate message data shared between all node's p2p protocols -// nodeId - message author id -// messageId - unique for requests, copied from request for responses -func NewMessageData(nodeId string, messageId string, gossip bool) *p2p.MessageData { - return &p2p.MessageData{ClientVersion: clientVersion, - NodeId: nodeId, - Timestamp: time.Now().Unix(), - Id: messageId, - Gossip: gossip} +func (n Node) verifyData(data []byte, signature []byte, signerHostId peer.ID) bool { + key := n.Peerstore().PubKey(signerHostId) + res, err := key.Verify(data, signature) + return res == true && err == nil } // Node type - implements one or more p2p protocols type Node struct { - host host.Host // lib-p2p host - *PingProtocol // ping protocol impl - *EchoProtocol // echo protocol impl + host.Host // lib-p2p host + *PingProtocol // ping protocol impl + *EchoProtocol // echo protocol impl } // create a new node with its implemented protocols func NewNode(host host.Host, done chan bool) *Node { - return &Node{host: host, - PingProtocol: NewPingProtocol(host, done), - EchoProtocol: NewEchoProtocol(host, done)} + node := &Node{Host: host} + node.PingProtocol = NewPingProtocol(node, done) + node.EchoProtocol = NewEchoProtocol(node, done) + return node } diff --git a/examples/multipro/ping.go b/examples/multipro/ping.go index 337b1b714f58cf4d547fe581fb8d3e92242e42d2..eec20668f2fbff89a17d070a47aabf048de9d93a 100644 --- a/examples/multipro/ping.go +++ b/examples/multipro/ping.go @@ -6,7 +6,6 @@ import ( "fmt" "log" - host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host" inet "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net" uuid "github.com/google/uuid" @@ -20,20 +19,20 @@ const pingResponse = "/ping/pingresp/0.0.1" // PingProtocol type type PingProtocol struct { - host host.Host // local host + node *Node // local host requests map[string]*p2p.PingRequest // used to access request data from response handlers done chan bool // only for demo purposes to stop main from terminating } -func NewPingProtocol(host host.Host, done chan bool) *PingProtocol { - p := &PingProtocol{host: host, requests: make(map[string]*p2p.PingRequest), done: done} - host.SetStreamHandler(pingRequest, p.onPingRequest) - host.SetStreamHandler(pingResponse, p.onPingResponse) +func NewPingProtocol(node *Node, done chan bool) *PingProtocol { + p := &PingProtocol{node: node, requests: make(map[string]*p2p.PingRequest), done: done} + node.SetStreamHandler(pingRequest, p.onPingRequest) + node.SetStreamHandler(pingResponse, p.onPingResponse) return p } // remote peer requests handler -func (p *PingProtocol) onPingRequest(s inet.Stream) { +func (p PingProtocol) onPingRequest(s inet.Stream) { // get request data data := &p2p.PingRequest{} @@ -48,10 +47,10 @@ func (p *PingProtocol) onPingRequest(s inet.Stream) { // send response to sender log.Printf("%s: Sending ping response to %s. Message id: %s...", s.Conn().LocalPeer(), s.Conn().RemotePeer(), data.MessageData.Id) - resp := &p2p.PingResponse{MessageData: NewMessageData(p.host.ID().String(), data.MessageData.Id, false), - Message: fmt.Sprintf("Ping response from %s", p.host.ID())} + resp := &p2p.PingResponse{MessageData: NewMessageData(p.node.ID().String(), data.MessageData.Id, false), + Message: fmt.Sprintf("Ping response from %s", p.node.ID())} - s, respErr := p.host.NewStream(context.Background(), s.Conn().RemotePeer(), pingResponse) + s, respErr := p.node.NewStream(context.Background(), s.Conn().RemotePeer(), pingResponse) if respErr != nil { log.Fatal(respErr) return @@ -65,7 +64,7 @@ func (p *PingProtocol) onPingRequest(s inet.Stream) { } // remote ping response handler -func (p *PingProtocol) onPingResponse(s inet.Stream) { +func (p PingProtocol) onPingResponse(s inet.Stream) { data := &p2p.PingResponse{} decoder := protobufCodec.Multicodec(nil).Decoder(bufio.NewReader(s)) err := decoder.Decode(data) @@ -87,14 +86,14 @@ func (p *PingProtocol) onPingResponse(s inet.Stream) { p.done <- true } -func (p *PingProtocol) Ping(node *Node) bool { - log.Printf("%s: Sending ping to: %s....", p.host.ID(), node.host.ID()) +func (p PingProtocol) Ping(node *Node) bool { + log.Printf("%s: Sending ping to: %s....", p.node.ID(), node.ID()) // create message data - req := &p2p.PingRequest{MessageData: NewMessageData(p.host.ID().String(), uuid.New().String(), false), - Message: fmt.Sprintf("Ping from %s", p.host.ID())} + req := &p2p.PingRequest{MessageData: NewMessageData(p.node.ID().String(), uuid.New().String(), false), + Message: fmt.Sprintf("Ping from %s", p.node.ID())} - s, err := p.host.NewStream(context.Background(), node.host.ID(), pingRequest) + s, err := p.node.NewStream(context.Background(), node.Host.ID(), pingRequest) if err != nil { log.Fatal(err) return false @@ -108,6 +107,6 @@ func (p *PingProtocol) Ping(node *Node) bool { // store ref request so response handler has access to it p.requests[req.MessageData.Id] = req - log.Printf("%s: Ping to: %s was sent. Message Id: %s, Message: %s", p.host.ID(), node.host.ID(), req.MessageData.Id, req.Message) + log.Printf("%s: Ping to: %s was sent. Message Id: %s, Message: %s", p.node.ID(), node.ID(), req.MessageData.Id, req.Message) return true } diff --git a/examples/multipro/protocol.go b/examples/multipro/protocol.go new file mode 100644 index 0000000000000000000000000000000000000000..b2672342d3e1e34b7b82ddf7ee9183a1c6e9f7b4 --- /dev/null +++ b/examples/multipro/protocol.go @@ -0,0 +1,41 @@ +package main + +import ( + "bufio" + p2p "github.com/libp2p/go-libp2p/examples/multipro/pb" + protobufCodec "github.com/multiformats/go-multicodec/protobuf" + inet "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net" + "log" + "time" + //host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host" + //"bytes" +) + +// node version +const clientVersion = "go-p2p-node/0.0.1" + +// helper method - writes a protobuf go data object to a network stream +// data - reference of protobuf go data object to send (not the object itself) +// s - network stream to write the data to +func sendDataObject(data interface{}, s inet.Stream) bool { + writer := bufio.NewWriter(s) + enc := protobufCodec.Multicodec(nil).Encoder(writer) + err := enc.Encode(data) + if err != nil { + log.Fatal(err) + return false + } + writer.Flush() + return true +} + +// helper method - generate message data shared between all node's p2p protocols +// nodeId - message author id +// messageId - unique for requests, copied from request for responses +func NewMessageData(nodeId string, messageId string, gossip bool) *p2p.MessageData { + return &p2p.MessageData{ClientVersion: clientVersion, + NodeId: nodeId, + Timestamp: time.Now().Unix(), + Id: messageId, + Gossip: gossip} +}