Commit bf7f80c3 authored by Aviv Eyal's avatar Aviv Eyal Committed by Steven Allen
Browse files

Refactoring

parent 45c3b5d4
...@@ -10,10 +10,9 @@ import ( ...@@ -10,10 +10,9 @@ import (
uuid "github.com/google/uuid" uuid "github.com/google/uuid"
"github.com/ipfs/go-ipfs/thirdparty/assert" "github.com/ipfs/go-ipfs/thirdparty/assert"
p2p "github.com/libp2p/go-libp2p/examples/multipro/pb" p2p "github.com/avive/go-libp2p/examples/multipro/pb"
protobufCodec "github.com/multiformats/go-multicodec/protobuf" protobufCodec "github.com/multiformats/go-multicodec/protobuf"
"gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host" "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host"
"gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
) )
// pattern: /protocol-name/request-or-response-message/version // pattern: /protocol-name/request-or-response-message/version
...@@ -52,15 +51,15 @@ func (e EchoProtocol) onEchoRequest(s inet.Stream) { ...@@ -52,15 +51,15 @@ func (e EchoProtocol) onEchoRequest(s inet.Stream) {
log.Fatal("Failed to authenticate message") log.Fatal("Failed to authenticate message")
return return
} else { } else {
log.Print("Authenticated request content was generated by claimed node :-)") log.Print("Authenticated request content was generated by author node :-)")
} }
log.Printf("%s: Sending echo response to %s. Message id: %s...", s.Conn().LocalPeer(), s.Conn().RemotePeer(), data.MessageData.Id) log.Printf("%s: Sending echo response to %s. Message id: %s...", s.Conn().LocalPeer(), s.Conn().RemotePeer(), data.MessageData.Id)
// send response to the request using the message string he provided // send response to the request using the message string he provided
resp := &p2p.EchoResponse{ resp := &p2p.EchoResponse{
MessageData: NewMessageData(peer.IDB58Encode(e.node.ID()), data.MessageData.Id, false), MessageData: NewMessageData(e.node, data.MessageData.Id, false),
Message: data.Message} Message: data.Message}
// sign the data // sign the data
...@@ -126,7 +125,7 @@ func (e EchoProtocol) Echo(host host.Host) bool { ...@@ -126,7 +125,7 @@ func (e EchoProtocol) Echo(host host.Host) bool {
// create message data // create message data
req := &p2p.EchoRequest{ req := &p2p.EchoRequest{
MessageData: NewMessageData(peer.IDB58Encode(e.node.ID()), uuid.New().String(), false), MessageData: NewMessageData(e.node, uuid.New().String(), false),
Message: fmt.Sprintf("Echo from %s", e.node.ID())} Message: fmt.Sprintf("Echo from %s", e.node.ID())}
signature, err := e.node.signProtoMessage(req) signature, err := e.node.signProtoMessage(req)
......
...@@ -27,6 +27,8 @@ func makeRandomNode(port int, done chan bool) *Node { ...@@ -27,6 +27,8 @@ func makeRandomNode(port int, done chan bool) *Node {
n, _ := swarm.NewNetwork(context.Background(), []ma.Multiaddr{listen}, pid, peerStore, nil) n, _ := swarm.NewNetwork(context.Background(), []ma.Multiaddr{listen}, pid, peerStore, nil)
host := bhost.New(n) host := bhost.New(n)
log.Printf("New host id (base58 multihash):%s, length:%d", host.ID().Pretty(), len(host.ID().Pretty()))
return NewNode(host, done) return NewNode(host, done)
} }
......
package main package main
import ( import (
"github.com/gogo/protobuf/proto"
host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host" host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host"
peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer" peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
"github.com/gogo/protobuf/proto" p2p "github.com/avive/go-libp2p/examples/multipro/pb"
p2p "github.com/libp2p/go-libp2p/examples/multipro/pb"
"log" "log"
) )
// Node type - a p2p host implementing one or more p2p protocols
type Node struct {
host.Host // lib-p2p host
*PingProtocol // ping protocol impl
*EchoProtocol // echo protocol impl
// add other protocols here...
}
// create a new node with its implemented protocols
func NewNode(host host.Host, done chan bool) *Node {
node := &Node{Host: host}
node.PingProtocol = NewPingProtocol(node, done)
node.EchoProtocol = NewEchoProtocol(node, done)
return node
}
func (n Node) authenticateMessage(message proto.Message, data *p2p.MessageData) bool { func (n Node) authenticateMessage(message proto.Message, data *p2p.MessageData) bool {
// store a temp ref to sig and remove it from data // store a temp ref to sig and remove it from data
sign := data.Sign sign := data.Sign
data.Sign = "" data.Sign = ""
//log.Print("Signature: %s", []byte(sign))
// marshall data without the sig to binary format // marshall data without the sig to binary format
bin, err := proto.Marshal(message) bin, err := proto.Marshal(message)
if err != nil { if err != nil {
// todo: log log.Fatal(err, "failed to marshal pb message")
return false return false
} }
...@@ -28,13 +41,12 @@ func (n Node) authenticateMessage(message proto.Message, data *p2p.MessageData) ...@@ -28,13 +41,12 @@ func (n Node) authenticateMessage(message proto.Message, data *p2p.MessageData)
data.Sign = sign data.Sign = sign
peerId, err := peer.IDB58Decode(data.NodeId) peerId, err := peer.IDB58Decode(data.NodeId)
if err != nil { if err != nil {
log.Fatal(err, "Failed to decode node id") log.Fatal(err, "Failed to decode node id from base58")
return false return false
} }
return n.verifyData(bin, []byte(sign), peerId) return n.verifyData(bin, []byte(sign), peerId, []byte(data.NodePubKey))
} }
func (n Node) signProtoMessage(message proto.Message) ([]byte, error) { func (n Node) signProtoMessage(message proto.Message) ([]byte, error) {
...@@ -52,25 +64,24 @@ func (n Node) signData(data []byte) ([]byte, error) { ...@@ -52,25 +64,24 @@ func (n Node) signData(data []byte) ([]byte, error) {
} }
// precondition: we have info about the signer peer in the local peer store // precondition: we have info about the signer peer in the local peer store
func (n Node) verifyData(data []byte, signature []byte, peerId peer.ID) bool { func (n Node) verifyData(data []byte, signature []byte, peerId peer.ID, pubKeyData []byte) bool {
// todo: restore pub key from message and use it
key := n.Peerstore().PubKey(peerId) key := n.Peerstore().PubKey(peerId)
//log.Print ("%s %s %s", peerId, key, peerId.String())
res, err := key.Verify(data, signature)
return res == true && err == nil
}
// Node type - a host with one or more implemented p2p protocols //todo: fix this
type Node struct { //key, err := key.UnmarshalPublicKey(pubKeyData)
host.Host // lib-p2p host
*PingProtocol // ping protocol impl
*EchoProtocol // echo protocol impl
// add other protocols here...
}
// create a new node with its implemented protocols if key == nil {
func NewNode(host host.Host, done chan bool) *Node { log.Fatal("Failed to find public key for %s in local peer store.", peerId.String())
node := &Node{Host: host} return false
node.PingProtocol = NewPingProtocol(node, done) }
node.EchoProtocol = NewEchoProtocol(node, done)
return node res, err := key.Verify(data, signature)
if err != nil {
log.Fatal("Error authenticating data")
return false
}
return res
} }
...@@ -39,7 +39,8 @@ type MessageData struct { ...@@ -39,7 +39,8 @@ type MessageData struct {
Id string `protobuf:"bytes,3,opt,name=id" json:"id,omitempty"` Id string `protobuf:"bytes,3,opt,name=id" json:"id,omitempty"`
Gossip bool `protobuf:"varint,4,opt,name=gossip" json:"gossip,omitempty"` Gossip bool `protobuf:"varint,4,opt,name=gossip" json:"gossip,omitempty"`
NodeId string `protobuf:"bytes,5,opt,name=nodeId" json:"nodeId,omitempty"` NodeId string `protobuf:"bytes,5,opt,name=nodeId" json:"nodeId,omitempty"`
Sign string `protobuf:"bytes,6,opt,name=sign" json:"sign,omitempty"` NodePubKey string `protobuf:"bytes,6,opt,name=nodePubKey" json:"nodePubKey,omitempty"`
Sign string `protobuf:"bytes,7,opt,name=sign" json:"sign,omitempty"`
} }
func (m *MessageData) Reset() { *m = MessageData{} } func (m *MessageData) Reset() { *m = MessageData{} }
...@@ -82,6 +83,13 @@ func (m *MessageData) GetNodeId() string { ...@@ -82,6 +83,13 @@ func (m *MessageData) GetNodeId() string {
return "" return ""
} }
func (m *MessageData) GetNodePubKey() string {
if m != nil {
return m.NodePubKey
}
return ""
}
func (m *MessageData) GetSign() string { func (m *MessageData) GetSign() string {
if m != nil { if m != nil {
return m.Sign return m.Sign
...@@ -202,21 +210,22 @@ func init() { ...@@ -202,21 +210,22 @@ func init() {
func init() { proto.RegisterFile("p2p.proto", fileDescriptor0) } func init() { proto.RegisterFile("p2p.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 244 bytes of a gzipped FileDescriptorProto // 261 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x8f, 0x31, 0x4f, 0xc3, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x8f, 0x31, 0x4f, 0xfb, 0x30,
0x10, 0x85, 0xe5, 0xb4, 0x04, 0x72, 0xa6, 0x0c, 0x37, 0x20, 0x0b, 0x31, 0x44, 0x11, 0x43, 0xa6, 0x10, 0xc5, 0xe5, 0xb4, 0xff, 0xf4, 0x9f, 0x33, 0x65, 0xb8, 0x01, 0x59, 0x08, 0xa1, 0x28, 0x62,
0x0c, 0x61, 0x65, 0x84, 0x81, 0x01, 0x09, 0x79, 0x60, 0x0f, 0xc9, 0x11, 0x2c, 0x35, 0xb6, 0xe9, 0xc8, 0x94, 0x21, 0xac, 0x8c, 0x30, 0x20, 0x84, 0x54, 0x79, 0x60, 0x4f, 0x93, 0x23, 0x58, 0x6a,
0x99, 0x9f, 0xc4, 0xff, 0x44, 0x5c, 0x83, 0xda, 0xfe, 0x80, 0x76, 0xb2, 0xdf, 0xd3, 0xb3, 0xdf, 0x6c, 0xd3, 0x73, 0x07, 0x3e, 0x20, 0xdf, 0x0b, 0xd5, 0x0d, 0x6a, 0xfa, 0x01, 0xca, 0xe4, 0x7b,
0xfb, 0xa0, 0x88, 0x6d, 0x6c, 0xe2, 0x26, 0xa4, 0x80, 0x2b, 0x39, 0xfa, 0xb0, 0xe6, 0x26, 0xb6, 0xef, 0x9e, 0xef, 0xe9, 0x07, 0x99, 0xaf, 0x7d, 0xe5, 0xb7, 0x2e, 0x38, 0x5c, 0xc6, 0xa7, 0x75,
0xb1, 0xfa, 0x51, 0xa0, 0x5f, 0x88, 0xb9, 0x1b, 0xe9, 0xb1, 0x4b, 0x1d, 0xde, 0xc1, 0xaa, 0x5f, 0x1b, 0xae, 0x7c, 0xed, 0x8b, 0x6f, 0x01, 0xf2, 0x95, 0x98, 0x9b, 0x9e, 0x1e, 0x9b, 0xd0, 0xe0,
0x3b, 0xf2, 0xe9, 0x8d, 0x36, 0xec, 0x82, 0x37, 0xaa, 0x54, 0x75, 0x61, 0x0f, 0x4d, 0xbc, 0x85, 0x1d, 0x2c, 0xdb, 0x8d, 0x21, 0x1b, 0xde, 0x68, 0xcb, 0xc6, 0x59, 0x25, 0x72, 0x51, 0x66, 0xfa,
0x22, 0xb9, 0x89, 0x38, 0x75, 0x53, 0x34, 0x59, 0xa9, 0xea, 0x85, 0xdd, 0x19, 0x78, 0x05, 0x99, 0xd4, 0xc4, 0x1b, 0xc8, 0x82, 0x19, 0x88, 0x43, 0x33, 0x78, 0x95, 0xe4, 0xa2, 0x9c, 0xe9, 0xa3,
0x1b, 0xcc, 0x42, 0x1e, 0x66, 0x6e, 0xc0, 0x6b, 0xc8, 0xc7, 0xc0, 0xec, 0xa2, 0x59, 0x96, 0xaa, 0x81, 0x97, 0x90, 0x98, 0x4e, 0xcd, 0xe2, 0xc7, 0xc4, 0x74, 0x78, 0x05, 0x69, 0xef, 0x98, 0x8d,
0xbe, 0xb0, 0xb3, 0xfa, 0xf3, 0x7d, 0x18, 0xe8, 0x79, 0x30, 0x67, 0x92, 0x9d, 0x15, 0x22, 0x2c, 0x57, 0xf3, 0x5c, 0x94, 0xff, 0xf5, 0xa8, 0xf6, 0xbe, 0x75, 0x1d, 0x3d, 0x77, 0xea, 0x5f, 0xcc,
0xd9, 0x8d, 0xde, 0xe4, 0xe2, 0xca, 0xbd, 0x22, 0xd0, 0xaf, 0xce, 0x8f, 0x96, 0xbe, 0xbe, 0x89, 0x8e, 0x0a, 0x6f, 0x01, 0xf6, 0xd3, 0x6a, 0xb7, 0x7e, 0xa1, 0x2f, 0x95, 0xc6, 0xdd, 0xc4, 0x41,
0x13, 0x3e, 0x80, 0x9e, 0x76, 0xab, 0x65, 0xa4, 0x6e, 0x6f, 0x9a, 0x03, 0xb6, 0x66, 0x8f, 0xcb, 0x84, 0x39, 0x9b, 0xde, 0xaa, 0x45, 0xdc, 0xc4, 0xb9, 0x20, 0x90, 0x2b, 0x63, 0x7b, 0x4d, 0x9f,
0xee, 0xc7, 0xd1, 0xc0, 0xf9, 0x2c, 0x65, 0x7c, 0x61, 0xff, 0x65, 0xf5, 0x01, 0x97, 0xdb, 0x1a, 0x3b, 0xe2, 0x80, 0x0f, 0x20, 0x87, 0x23, 0x55, 0x84, 0x90, 0xf5, 0x75, 0x75, 0xc2, 0x5e, 0x4d,
0x8e, 0xc1, 0x33, 0x1d, 0xad, 0x87, 0x40, 0x3f, 0xf5, 0x9f, 0xe1, 0x04, 0x38, 0xdb, 0x9a, 0xe3, 0xb8, 0xf5, 0x34, 0x8e, 0x0a, 0x16, 0xa3, 0x8c, 0x70, 0x99, 0xfe, 0x95, 0xc5, 0x3b, 0x5c, 0x1c,
0xe2, 0xbc, 0xe7, 0xf2, 0xc3, 0xfd, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb9, 0xf8, 0x88, 0xca, 0x6a, 0xd8, 0x3b, 0xcb, 0x74, 0xb6, 0x1e, 0x02, 0xf9, 0xd4, 0x7e, 0xb8, 0x3f, 0xc0, 0x39, 0xd4,
0x68, 0x02, 0x00, 0x00, 0x9c, 0x17, 0x67, 0x9d, 0xc6, 0x0b, 0xf7, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x14, 0x4d, 0xf8,
0x0c, 0x88, 0x02, 0x00, 0x00,
} }
...@@ -6,11 +6,12 @@ package protocols.p2p; ...@@ -6,11 +6,12 @@ package protocols.p2p;
message MessageData { message MessageData {
// shared between all requests // shared between all requests
string clientVersion = 1; // client version string clientVersion = 1; // client version
int64 timestamp = 2; // unix time int64 timestamp = 2; // unix time
string id = 3; // allows requesters to use request data when processing a response string id = 3; // allows requesters to use request data when processing a response
bool gossip = 4; // true to have receiver peer gossip the message to neighbors bool gossip = 4; // true to have receiver peer gossip the message to neighbors
string nodeId = 5; // id of node that created the message (not the peer that may have sent it) string nodeId = 5; // id of node that created the message (not the peer that may have sent it). =base58(mh(sha256(nodePubKey)))
bytes sign = 6; // signature of message data + method specific data by message authoring node string nodePubKey = 6; // node's Secp256k1 public key bytes (32bytes)
string sign = 7; // signature of message data + method specific data by message authoring node
} }
//// ping protocol //// ping protocol
......
...@@ -9,10 +9,9 @@ import ( ...@@ -9,10 +9,9 @@ import (
inet "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net" inet "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net"
uuid "github.com/google/uuid" uuid "github.com/google/uuid"
p2p "github.com/libp2p/go-libp2p/examples/multipro/pb" p2p "github.com/avive/go-libp2p/examples/multipro/pb"
protobufCodec "github.com/multiformats/go-multicodec/protobuf" protobufCodec "github.com/multiformats/go-multicodec/protobuf"
"gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host" "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host"
"gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
) )
// pattern: /protocol-name/request-or-response-message/version // pattern: /protocol-name/request-or-response-message/version
...@@ -59,7 +58,7 @@ func (p PingProtocol) onPingRequest(s inet.Stream) { ...@@ -59,7 +58,7 @@ func (p PingProtocol) onPingRequest(s inet.Stream) {
// generate response message // generate response message
log.Printf("%s: Sending ping response to %s. Message id: %s...", s.Conn().LocalPeer(), s.Conn().RemotePeer(), data.MessageData.Id) 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(peer.IDB58Encode(p.node.ID()), data.MessageData.Id, false), resp := &p2p.PingResponse{MessageData: NewMessageData(p.node, data.MessageData.Id, false),
Message: fmt.Sprintf("Ping response from %s", p.node.ID())} Message: fmt.Sprintf("Ping response from %s", p.node.ID())}
// sign the data // sign the data
...@@ -122,7 +121,7 @@ func (p PingProtocol) Ping(host host.Host) bool { ...@@ -122,7 +121,7 @@ func (p PingProtocol) Ping(host host.Host) bool {
log.Printf("%s: Sending ping to: %s....", p.node.ID(), host.ID()) log.Printf("%s: Sending ping to: %s....", p.node.ID(), host.ID())
// create message data // create message data
req := &p2p.PingRequest{MessageData: NewMessageData(peer.IDB58Encode(p.node.ID()), uuid.New().String(), false), req := &p2p.PingRequest{MessageData: NewMessageData(p.node, uuid.New().String(), false),
Message: fmt.Sprintf("Ping from %s", p.node.ID())} Message: fmt.Sprintf("Ping from %s", p.node.ID())}
// sign the data // sign the data
......
...@@ -2,14 +2,13 @@ package main ...@@ -2,14 +2,13 @@ package main
import ( import (
"bufio" "bufio"
p2p "github.com/libp2p/go-libp2p/examples/multipro/pb" p2p "github.com/avive/go-libp2p/examples/multipro/pb"
protobufCodec "github.com/multiformats/go-multicodec/protobuf" protobufCodec "github.com/multiformats/go-multicodec/protobuf"
inet "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net" inet "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net"
"log" "log"
"time" "time"
//host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host"
//"bytes"
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
"gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
) )
// node version // node version
...@@ -31,11 +30,19 @@ func sendProtoMessage(data proto.Message, s inet.Stream) bool { ...@@ -31,11 +30,19 @@ func sendProtoMessage(data proto.Message, s inet.Stream) bool {
} }
// helper method - generate message data shared between all node's p2p protocols // 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 // messageId - unique for requests, copied from request for responses
func NewMessageData(nodeId string, messageId string, gossip bool) *p2p.MessageData { func NewMessageData(node *Node, messageId string, gossip bool) *p2p.MessageData {
// this creates a protobuf data for a public key
nodePubKey, err := node.Peerstore().PubKey(node.ID()).Bytes()
if err != nil {
panic("Failed to get public key for sender node from peer store.")
}
return &p2p.MessageData{ClientVersion: clientVersion, return &p2p.MessageData{ClientVersion: clientVersion,
NodeId: nodeId, NodeId: peer.IDB58Encode(node.ID()),
NodePubKey: string(nodePubKey),
Timestamp: time.Now().Unix(), Timestamp: time.Now().Unix(),
Id: messageId, Id: messageId,
Gossip: gossip} Gossip: gossip}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment