From 842b6b85ade0ef4d3fe64b9d3e1adf83c0d87a91 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Fri, 2 Mar 2018 23:09:05 +0100 Subject: [PATCH] whisper: Initial wnode support for libp2p This doesn't currently handle streams, peers nor the api. --- cmd/wnode/main.go | 51 +++++++++++++++++++------------- whisper/whisperv6/devp2p_glue.go | 16 ++++++++-- whisper/whisperv6/doc.go | 3 ++ whisper/whisperv6/libp2p_glue.go | 34 +++++++++++++++++++-- whisper/whisperv6/whisper.go | 3 ++ 5 files changed, 82 insertions(+), 25 deletions(-) diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go index 99c0bab563..b27a1189c8 100644 --- a/cmd/wnode/main.go +++ b/cmd/wnode/main.go @@ -53,7 +53,7 @@ const entropySize = 32 // singletons var ( - server WhisperServer + server whisper.WhisperServer shh *whisper.Whisper done chan struct{} mailServer mailserver.WMailServer @@ -277,21 +277,26 @@ func initialize() { } if *useLibP2P { - server = NewLibP2PWhisperServer() + server, err = whisper.NewLibP2PWhisperServer() + if err != nil { + utils.Fatalf("Error starting the libp2p client: %v", err) + } } else { - server = &p2p.Server{ - Config: p2p.Config{ - PrivateKey: nodeid, - MaxPeers: maxPeers, - Name: common.MakeName("wnode", "6.1"), - Protocols: shh.Protocols(), - ListenAddr: *argIP, - NAT: nat.Any(), - BootstrapNodes: peers, - StaticNodes: peers, - TrustedNodes: peers, + server = &whisper.DevP2PWhisperServer{ + &p2p.Server{ + Config: p2p.Config{ + PrivateKey: nodeid, + MaxPeers: maxPeers, + Name: common.MakeName("wnode", "6.1"), + Protocols: shh.Protocols(), + ListenAddr: *argIP, + NAT: nat.Any(), + BootstrapNodes: peers, + StaticNodes: peers, + TrustedNodes: peers, + }, }, - }, + } } } @@ -303,7 +308,7 @@ func startServer() error { } fmt.Printf("my public key: %s \n", common.ToHex(crypto.FromECDSAPub(&asymKey.PublicKey))) - fmt.Println(server.NodeInfo().Enode) + fmt.Println(server.Enode()) if *bootstrapMode { configureNode() @@ -686,7 +691,8 @@ func writeMessageToFile(dir string, msg *whisper.ReceivedMessage, show bool) { } func requestExpiredMessagesLoop() { - var key, peerID, bloom []byte + var key, bloom []byte + var peerID string var timeLow, timeUpp uint32 var t string var xt whisper.TopicType @@ -756,12 +762,15 @@ func requestExpiredMessagesLoop() { } } -func extractIDFromEnode(s string) []byte { - n, err := discover.ParseNode(s) - if err != nil { - utils.Fatalf("Failed to parse enode: %s", err) +func extractIDFromEnode(s string) string { + if !*useLibP2P { + n, err := discover.ParseNode(s) + if err != nil { + utils.Fatalf("Failed to parse enode: %s", err) + } + return n.ID.String() } - return n.ID[:] + return "" } // obfuscateBloom adds 16 random bits to the the bloom diff --git a/whisper/whisperv6/devp2p_glue.go b/whisper/whisperv6/devp2p_glue.go index 9ac46d238b..6d36011151 100644 --- a/whisper/whisperv6/devp2p_glue.go +++ b/whisper/whisperv6/devp2p_glue.go @@ -21,9 +21,21 @@ import ( ) type DevP2PWhisperServer struct { - server *p2p.Server + Server *p2p.Server } func (server *DevP2PWhisperServer) Start() error { - return server.Start() + return server.Server.Start() +} + +func (server *DevP2PWhisperServer) Stop() { + server.Server.Stop() +} + +func (server *DevP2PWhisperServer) PeerCount() int { + return server.Server.PeerCount() +} + +func (server *DevP2PWhisperServer) Enode() string { + return server.Server.NodeInfo().Enode } \ No newline at end of file diff --git a/whisper/whisperv6/doc.go b/whisper/whisperv6/doc.go index 900c06c727..8cde3a719d 100644 --- a/whisper/whisperv6/doc.go +++ b/whisper/whisperv6/doc.go @@ -77,6 +77,9 @@ const ( DefaultTTL = 50 // seconds DefaultSyncAllowance = 10 // seconds + + WhisperPort = 5348 + WhisperProtocolString = "/whisper/6.1" ) type unknownVersionError uint64 diff --git a/whisper/whisperv6/libp2p_glue.go b/whisper/whisperv6/libp2p_glue.go index 9e46d4e7c3..a8eddadfd5 100644 --- a/whisper/whisperv6/libp2p_glue.go +++ b/whisper/whisperv6/libp2p_glue.go @@ -17,13 +17,17 @@ package whisperv6 import ( + "context" "bytes" "encoding/binary" "fmt" "math" "github.com/ethereum/go-ethereum/p2p" + libp2p "github.com/libp2p/go-libp2p" + host "github.com/libp2p/go-libp2p-host" inet "github.com/libp2p/go-libp2p-net" + crypto "github.com/libp2p/go-libp2p-crypto" ) // LibP2PStream is a wrapper used to implement the MsgReadWriter @@ -109,12 +113,38 @@ func (stream *LibP2PStream) WriteMsg(msg p2p.Msg) error { } type LibP2PWhisperServer struct { + Host host.Host } func (server *LibP2PWhisperServer) Start() error { return nil } -func NewLibP2PWhisperServer() WhisperServer { - return &LibP2PWhisperServer{} +// Stop stops the server +func (server *LibP2PWhisperServer) Stop() { + server.Host.Close() +} + +// PeerCount returns the peer count for the node +func (server *LibP2PWhisperServer) PeerCount() int { + return 0 +} + +// Enode returns the enode address of the node +func (server *LibP2PWhisperServer) Enode() string { + return server.Host.Addrs()[0].String() +} + +func NewLibP2PWhisperServer() (WhisperServer, error) { + priv, _, err := crypto.GenerateKeyPair(crypto.Ed25519, 384) + opts := []libp2p.Option{ + libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", WhisperPort)), + libp2p.Identity(priv), +} + + h, err := libp2p.New(context.Background(), opts...) + if err != nil { + return nil, fmt.Errorf("Error setting up the libp2p network: %s", err) + } + return &LibP2PWhisperServer{h}, nil } \ No newline at end of file diff --git a/whisper/whisperv6/whisper.go b/whisper/whisperv6/whisper.go index 0574ddde4c..eb0dc6ec47 100644 --- a/whisper/whisperv6/whisper.go +++ b/whisper/whisperv6/whisper.go @@ -58,6 +58,9 @@ const ( type WhisperServer interface { Start() error + Stop() + PeerCount() int + Enode() string } // Whisper represents a dark communication interface through the Ethereum