Refactoring

This commit is contained in:
Aviv Eyal 2017-11-28 22:17:38 +02:00 committed by Steven Allen
parent 45c3b5d4a3
commit bf7f80c30a
7 changed files with 94 additions and 66 deletions

View File

@ -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) {
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 {
// 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)

View File

@ -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)
} }

View File

@ -1,26 +1,39 @@
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)
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) {
} }
// 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())
//todo: fix this
//key, err := key.UnmarshalPublicKey(pubKeyData)
if key == nil {
log.Fatal("Failed to find public key for %s in local peer store.", peerId.String())
return false
}
res, err := key.Verify(data, signature) res, err := key.Verify(data, signature)
return res == true && err == nil if err != nil {
log.Fatal("Error authenticating data")
return false
} }
// Node type - a host with one or more implemented p2p protocols return res
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
} }

View File

@ -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 {
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() {
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,
} }

View File

@ -9,8 +9,9 @@ message MessageData {
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

View File

@ -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) {
// 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 {
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

View File

@ -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 {
} }
// 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}