From 8d913df995b7c3187fcd50eb9727f58a0ffb81f5 Mon Sep 17 00:00:00 2001 From: rairyx Date: Thu, 11 Jul 2019 10:53:40 -0700 Subject: [PATCH 1/8] Integrate with lastest go-libp2p --- pubsub/raven.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pubsub/raven.go b/pubsub/raven.go index c7fe672..9a45e6b 100644 --- a/pubsub/raven.go +++ b/pubsub/raven.go @@ -9,23 +9,21 @@ import ( _ "time" "strconv" "github.com/ipfs/go-log" - libp2p "github.com/libp2p/go-libp2p" - host "github.com/libp2p/go-libp2p-host" + "github.com/libp2p/go-libp2p" + host "github.com/libp2p/go-libp2p-core/host" inet "github.com/libp2p/go-libp2p-net" peerstore "github.com/libp2p/go-libp2p-peerstore" libp2pdht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p-crypto" logging "github.com/whyrusleeping/go-logging" - floodsub "github.com/libp2p/go-floodsub" + floodsub "github.com/libp2p/go-libp2p-pubsub" ma "github.com/multiformats/go-multiaddr" ) var logger = log.Logger("raven") var ho host.Host -//var TopicName string = "libp2p-demo-chat" -//h("libp2p-demo-chat") = "RDEpsjSPrAZF9JCK5REt3tao" - rust uses the hash unlike js/go () var TopicName string = "RDEpsjSPrAZF9JCK5REt3tao" func parseArgs() (bool, string, int) { @@ -56,7 +54,7 @@ func handleConn(conn inet.Conn) { } func main() { - log.SetAllLoggers(logging.INFO) + log.SetAllLoggers(logging.DEBUG) log.SetLogLevel("raven", "debug") ctx := context.Background() From 482f4f8846938aff5dfa322e716a2da69766a5e9 Mon Sep 17 00:00:00 2001 From: rairyx Date: Fri, 19 Jul 2019 22:55:35 -0700 Subject: [PATCH 2/8] Test gossipsub --- pubsub/raven.go | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/pubsub/raven.go b/pubsub/raven.go index 9a45e6b..e20017a 100644 --- a/pubsub/raven.go +++ b/pubsub/raven.go @@ -17,7 +17,7 @@ import ( "github.com/libp2p/go-libp2p-crypto" logging "github.com/whyrusleeping/go-logging" - floodsub "github.com/libp2p/go-libp2p-pubsub" + gossipsub "github.com/libp2p/go-libp2p-pubsub" ma "github.com/multiformats/go-multiaddr" ) @@ -45,13 +45,6 @@ func parseArgs() (bool, string, int) { return bBootstrap, privKeyFilePath, listenPort } -func handleConn(conn inet.Conn) { - ctx := context.Background() - h := ho - fmt.Printf(" New peer joined: %v\n", conn.RemoteMultiaddr().String()) - _ = h - _ = ctx -} func main() { log.SetAllLoggers(logging.DEBUG) @@ -118,8 +111,8 @@ func main() { if err = kademliaDHT.Bootstrap(ctx); err != nil { panic(err) } - // Construct a floodsub instance for this host - fsub, err := floodsub.NewFloodSub(ctx, host, floodsub.WithMessageSigning(false)) + // Construct a gossipsub instance for this host + gsub, err := gossipsub.NewGossipSub(ctx, host, gossipsub.WithMessageSigning(false)) if err != nil { fmt.Println("Error (floodsub.NewFloodSub): %v", err) panic(err) @@ -154,7 +147,7 @@ func main() { // // Subscribe to the topic and wait for messages published on that topic // - sub, err := fsub.Subscribe(TopicName) + sub, err := gsub.Subscribe(TopicName) if err != nil { fmt.Println("Error (fsub.Subscribe): %v", err) panic(err) @@ -190,7 +183,7 @@ func main() { // Now, wait for input from the user, and send that out! scan := bufio.NewScanner(os.Stdin) for scan.Scan() { - if err := fsub.Publish(TopicName, scan.Bytes()); err != nil { + if err := gsub.Publish(TopicName, scan.Bytes()); err != nil { panic(err) } } From d018ef694aee6f6ca467c66cb83a24fb2f9a4935 Mon Sep 17 00:00:00 2001 From: rairyx Date: Fri, 19 Jul 2019 23:03:41 -0700 Subject: [PATCH 3/8] Add private key file for 4th node --- util/private_key.bin.peer.d9 | Bin 0 -> 2354 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 util/private_key.bin.peer.d9 diff --git a/util/private_key.bin.peer.d9 b/util/private_key.bin.peer.d9 new file mode 100755 index 0000000000000000000000000000000000000000..fcb3e107b8207708211a17dec2a4a348f979519e GIT binary patch literal 2354 zcmV-23C;Eh01~YdFoFpw0s#O5f&u{m*_chL5y{mp>DZ+uaJPq&wF>+F%DF@&9#TY1 zp@=eCy>+T){S@eV4-td$a~g)B)gb@4H%&pf!h#wqT%EnSjz-RTFJ4yiLYvy}d3c|- z@$l^wU>%i_85V1BuFTlwCl8o>bj|D3=B(a6UyrJC^)1N71`_135iwOSFNvp@pLbUg zTi)T6l@#~iJo0nKPk(0J+r9w>D{KFkMwT~9PLW0>b{2I>*L8Ho*P5+>L;hHhaQDVz@5hj z?XSJ?Xrsbq1wbcaFL`ySbL2#j07t2D527__``JY}QSW%44D`9=ytC0pF`_}B#?=)@ z9!= zE5y?X`I|+*)6xok@%yb{AB(J7{8eL&_)}YS-U*Ls%mHdSM;}zv6t9R87||SXfPYC* zgMEV7@tJ+(;f>UoMJ+% zYdWh;??hu(Lvx%=BHn!6a^Xs**v~WKxWrzv%7a`AP`!247P_cZ{L7 z8mKh|_rv+Ls7B$5e7a3f7UePz=vkV{C;ovD?_G-Wu&Goctp(@l6*irsPlkmpT|Ju0;3Ne37CK ztLmm|*$r>JW@JzLm*cclLa8y{17r--z#Fi!nBILJ_t3c2r+h76;5NFNXQ}%%gB$-W zqmz1U0i*W)DlG6%|5V~Issj!Hy9(iNGQP0eBiabSg?CtECI(%^R&qq7B# zG2Soa19%`<6wjK>>OzWYr{O~IEWB}cmc;SWRlk0csKNgPnq+N@p|S{rN{bb5p6S81O!g`OB)m;QAhYWoT z>9;hB=?cSOxlD90U>vdSx>o{%0RaH#l=JC{EN8XF`4D6HIqXexH8y4*G?AFEvmrUx z$J=o|p7(T42lVt^u^jR$3DkP?YJ+lx z@MonB+>(!;;wOPmPodFFS3uT1Sd{osjf1%ku1nv%1cwvC0Op^Q#a8k@c2cBmTHzu> zV?5hQ2t0_(nHUCGjLuY#c1OF@m;U)CM6FRh*=;;-3puaa1gRmJPkp0+gHPuRrs zL9)y-5r%LhAK3h0tSTK3RW;)Rf&l>lz8jLngxdP?_=3yr`wOD0i8!3ff_XV9=EeTqp6tNvO`?i9ApKDspStfBb`?$6QEqj{+Fwc7}?kGMhEy z5fmH7%BbM^xZ}c-Lu1(!)h_9g0)hbmZV6PZPQ{L~%u~Pm0AyunmoT}UWEIY6qH~u5 z2??pUaP%xF3DA0ers=M&|GCzdrN#^FLND}aO~aeceOl50!#-@H05ZGsMGsD@?Iv3` z`*m}P^}sCCnMV{xSq&L-eYdC6Bx?q}#%Q;KBKxL^w5Z}0{Y1D>a>9MVwDddZZ5@?^ z)z6uS2zaGx%5wkvWAEe2LNJYeE4=!~smU0fSembl(bm}sy(aF6D=;f^C+3F81G0v1 z(%`Ty{*XzUs9)yx&|DdiHd2spPv%~o`DsWm><+_>H8PPS+~o7XsJgVojA6lP^pxxe z2_D*dGlqmdoH6mlS(@~h!bMie0)hbn0DwM|{!-Rq+u3TydpvfJ0h1H#9M?2=XffM(Bp>dX%BG{nE9@mvE z=YL_A Date: Fri, 19 Jul 2019 23:10:08 -0700 Subject: [PATCH 4/8] Update README.md --- README.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7029358..db1ef52 100644 --- a/README.md +++ b/README.md @@ -42,22 +42,18 @@ This peer, which is not in bootstrapper mode, creates a node, subscribes to the ``` cd pubsub -./raven ../util/private_key.bin.peer.W6 6001 +./raven ../util/private_key.bin.peer.w6 6001 ``` -**Fourth terminal**: Create a JS peer to connect to bootstrap and publish on topic +**Fourth terminal**: Create a third go peer to connect to bootstrap and publish on topic ``` -cd pubsub/js -npm install # first time only -node index.js /ip4/127.0.0.1/tcp/5555/ipfs/QmehVYruznbyDZuHBV4vEHESpDevMoAovET6aJ9oRuEzWa -``` - -This JS peer will accept lines of text typed on stdin, and publish them on the PubSub topic. +cd pubsub +./raven ../util/private_key.bin.peer.d9 6002 -(Note that the JS peer generates a new identity (public/private keypair) each time, and prints its public key to stdout. This is a deficiency in the demo; to be consistent with the Go code it should accept a private key on the CLI.) +``` If you return to the second, third or fourth terminals and type a message, the bootstrapper and the other 2 peers will all print your message. From 150ecf18bfabf476cc7db1517ef1b1fae0e6adbf Mon Sep 17 00:00:00 2001 From: rairyx Date: Fri, 19 Jul 2019 23:13:39 -0700 Subject: [PATCH 5/8] remove old files --- pubsub/pubsub-interop.go | 181 --------------------------------------- pubsub/raven.go | 4 +- 2 files changed, 2 insertions(+), 183 deletions(-) delete mode 100644 pubsub/pubsub-interop.go diff --git a/pubsub/pubsub-interop.go b/pubsub/pubsub-interop.go deleted file mode 100644 index 22e964d..0000000 --- a/pubsub/pubsub-interop.go +++ /dev/null @@ -1,181 +0,0 @@ -package main - -import ( - "bufio" - "context" - "fmt" - "io/ioutil" - "os" - _ "time" - - libp2p "github.com/libp2p/go-libp2p" - host "github.com/libp2p/go-libp2p-host" - inet "github.com/libp2p/go-libp2p-net" - peerstore "github.com/libp2p/go-libp2p-peerstore" - - "github.com/libp2p/go-libp2p-crypto" - - floodsub "github.com/libp2p/go-floodsub" - ma "github.com/multiformats/go-multiaddr" -) - -var ho host.Host - -//var TopicName string = "libp2p-demo-chat" -//h("libp2p-demo-chat") = "RDEpsjSPrAZF9JCK5REt3tao" - rust uses the hash unlike js/go () -var TopicName string = "RDEpsjSPrAZF9JCK5REt3tao" - -func parseArgs() (bool, string) { - usage := fmt.Sprintf("Usage: %s PRIVATE_KEY [--bootstrapper]\n\nPRIVATE_KEY is the path to a private key like '../util/private_key.bin'\n--bootstrapper to run in bootstrap mode (creates a DHT and listens for peers)\n", os.Args[0]) - var bBootstrap bool = false - var privKeyFilePath string - var args []string = os.Args[1:] - if (len(args) == 0) || (len(args) > 2) { - fmt.Printf("Error: wrong number of arguments\n\n%s", usage) - os.Exit(1) - } - privKeyFilePath = args[0] - if (len(args) == 2) && (args[1] == "--bootstrapper") { - bBootstrap = true - } - return bBootstrap, privKeyFilePath -} - -func handleConn(conn inet.Conn) { - ctx := context.Background() - h := ho - fmt.Printf(" New peer joined: %v\n", conn.RemoteMultiaddr().String()) - _ = h - _ = ctx -} - -func main() { - ctx := context.Background() - - bBootstrap, privKeyFilePath := parseArgs() - fmt.Printf("Starting up in ") - if bBootstrap { - fmt.Printf("bootstrapper mode (port 5555)") - } else { - fmt.Printf("peer mode (port 6000)") - } - fmt.Printf("\nPrivate key '%s'\n", privKeyFilePath) - - // - // Read the private key and unmarshall it into struct - // - var privBytes []byte - privBytes, err := ioutil.ReadFile(privKeyFilePath) - if err != nil { - fmt.Println("ioutil.ReadFile: failed: %v", err) - panic(err) - } - - var priv crypto.PrivKey - priv, err = crypto.UnmarshalPrivateKey(privBytes) - if err != nil { - fmt.Println("crypto.UnmarshalPrivateKey: failed: %v", err) - panic(err) - } - - // - // Construct our libp2p host - // - var host host.Host - if bBootstrap { - host, err = libp2p.New(ctx, - libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/5555"), - libp2p.Identity(priv), - ) - } else { - host, err = libp2p.New(ctx, - libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/6000"), - libp2p.Identity(priv), - ) - } - if err != nil { - fmt.Println("libp2p.New: failed: %v", err) - panic(err) - } - - // - // Construct a floodsub instance for this host - // - fsub, err := floodsub.NewFloodSub(ctx, host, floodsub.WithMessageSigning(false)) - if err != nil { - fmt.Println("Error (floodsub.NewFloodSub): %v", err) - panic(err) - } - - // - // If we are the bootstrap node, we don't try to connect to any peers. - // Else: try to connect to the bootstrap node. - // - const bootstrapAddrIP4Str string = "127.0.0.1" - if !bBootstrap { - var bootstrapMultiAddr ma.Multiaddr - var pinfo *peerstore.PeerInfo - bootstrapMultiAddrStr := fmt.Sprintf("/ip4/%s/tcp/5555/ipfs/QmehVYruznbyDZuHBV4vEHESpDevMoAovET6aJ9oRuEzWa", bootstrapAddrIP4Str) - fmt.Printf("bootstrapping to '%s'...\n", bootstrapMultiAddrStr) - bootstrapMultiAddr, err := ma.NewMultiaddr(bootstrapMultiAddrStr) - if err != nil { - fmt.Println("Error (ma.NewMultiaddr): %v", err) - panic(err) - } - - pinfo, err = peerstore.InfoFromP2pAddr(bootstrapMultiAddr) - if err != nil { - fmt.Println("Error (ma.NewMultiaddr): %v", err) - panic(err) - } - - if err := host.Connect(ctx, *pinfo); err != nil { - fmt.Println("bootstrapping to peer failed: ", err) - } - } - - // - // Subscribe to the topic and wait for messages published on that topic - // - sub, err := fsub.Subscribe(TopicName) - if err != nil { - fmt.Println("Error (fsub.Subscribe): %v", err) - panic(err) - } - - // Go and listen for messages from them, and print them to the screen - go func() { - for { - msg, err := sub.Next(ctx) - if err != nil { - fmt.Println("Error (sub.Next): %v", err) - panic(err) - } - - //fmt.Printf("%s: %s\n", msg.GetFrom(), string(msg.GetData())) - fmt.Printf("%s\n", string(msg.GetData())) - } - }() - - // SetConnHandler() should not normally be called. Instead, - // use Notify() and pass it a functioon. (The problem with - // SetConnHandler() is that it takes control of the connection.) - host.Network().Notify(&inet.NotifyBundle{ - ConnectedF: func(n inet.Network, c inet.Conn) { - fmt.Println("Got a connection:", c.RemotePeer()) - }, - }) - if bBootstrap { - fmt.Println("Bootstrapper running.\nPubSub object instantiated using FloodSubRouter.\nCtrl+C to exit.") - for true { - } - } else { - // Now, wait for input from the user, and send that out! - scan := bufio.NewScanner(os.Stdin) - for scan.Scan() { - if err := fsub.Publish(TopicName, scan.Bytes()); err != nil { - panic(err) - } - } - } -} diff --git a/pubsub/raven.go b/pubsub/raven.go index e20017a..a32c49a 100644 --- a/pubsub/raven.go +++ b/pubsub/raven.go @@ -114,7 +114,7 @@ func main() { // Construct a gossipsub instance for this host gsub, err := gossipsub.NewGossipSub(ctx, host, gossipsub.WithMessageSigning(false)) if err != nil { - fmt.Println("Error (floodsub.NewFloodSub): %v", err) + fmt.Println("Error (gossipsub.NewGossipSub): %v", err) panic(err) } const bootstrapAddrIP4Str string = "127.0.0.1" @@ -176,7 +176,7 @@ func main() { }, }) if bBootstrap { - fmt.Println("Bootstrapper running.\nPubSub object instantiated using FloodSubRouter.\nCtrl+C to exit.") + fmt.Println("Bootstrapper running.\nPubSub object instantiated using GossipSubRouter.\nCtrl+C to exit.") for true { } } else { From db4ccf1fb66c497b68497e7f4a4fbedf843288ca Mon Sep 17 00:00:00 2001 From: rairyx Date: Wed, 24 Jul 2019 10:40:25 -0700 Subject: [PATCH 6/8] Fix bootnode hang up --- pubsub/raven.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pubsub/raven.go b/pubsub/raven.go index a32c49a..775d277 100644 --- a/pubsub/raven.go +++ b/pubsub/raven.go @@ -177,8 +177,9 @@ func main() { }) if bBootstrap { fmt.Println("Bootstrapper running.\nPubSub object instantiated using GossipSubRouter.\nCtrl+C to exit.") - for true { - } + // for true { + // } + select {} } else { // Now, wait for input from the user, and send that out! scan := bufio.NewScanner(os.Stdin) From 3dedade5065d2108e18921675c6f4a808b7d491d Mon Sep 17 00:00:00 2001 From: rairyx Date: Mon, 29 Jul 2019 14:30:58 -0700 Subject: [PATCH 7/8] Add TLS1.3 support --- pubsub/raven.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pubsub/raven.go b/pubsub/raven.go index 775d277..da3d39a 100644 --- a/pubsub/raven.go +++ b/pubsub/raven.go @@ -15,7 +15,6 @@ import ( peerstore "github.com/libp2p/go-libp2p-peerstore" libp2pdht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p-crypto" - logging "github.com/whyrusleeping/go-logging" gossipsub "github.com/libp2p/go-libp2p-pubsub" ma "github.com/multiformats/go-multiaddr" @@ -26,6 +25,12 @@ var ho host.Host var TopicName string = "RDEpsjSPrAZF9JCK5REt3tao" + + +func init() { + os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",tls13=1") +} + func parseArgs() (bool, string, int) { usage := fmt.Sprintf("Usage: %s PRIVATE_KEY PORT [--bootstrapper] \n\nPRIVATE_KEY is the path to a private key like '../util/private_key.bin'\n PORT is port to listen on, default is 6000\n--bootstrapper to run in bootstrap mode (creates a DHT and listens for peers)\n", os.Args[0]) var bBootstrap bool = false From af9a07738a03190577ccffc5f5c91317da3df2e1 Mon Sep 17 00:00:00 2001 From: rairyx Date: Thu, 15 Aug 2019 16:55:54 -0700 Subject: [PATCH 8/8] update README.md --- README.md | 4 ++-- pubsub/raven.go | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index db1ef52..f7e603f 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ Blockchain has enabled decentralized value transfer. A bigger future is decentralized communication. One step forward is anonymous decentralized communication which provides a censorship resistence privacy preserved communication network that anyone can send/receive, broadcast messages anonymously without revealing message metadata(sender, receiver, who send to whom, etc). It will find broad use cases, e.g., whistleblowing, anonymous public channel, incident reporting, privacy served messaging in Dapps etc. -Anonymity is achieved by implementing Dandelion protocol on top of libp2p's pub/sub module, dandelion is a privacy preserving protocol to make message sender anonymous, it has 2 phases, the first phase is stem phase, where messages go through a psuedo-random path, the second phase is fluffing, at a random time of the stem phase, the message is diffused to its surrounding peers, so the third party observer cannot track back the node original node who send the message, because the message is relayed through an anonymous graph. Message broadcasting is implemented by libp2p floodsub. +Anonymity is achieved by implementing Dandelion++ protocol on top of libp2p's pub/sub module, Dandelion is a privacy preserving protocol to make message sender anonymous, it has 2 phases, the first phase is stem phase, where messages go through a psuedo-random path, the second phase is fluffing, at a random time of the stem phase, the message is diffused to its surrounding peers, so the third party observer cannot track back the node original node who send the message, because the message is relayed through an anonymous graph. Message broadcasting is implemented by libp2p floodsub. Dandelion++ is an improved version of Dandelion. -**Dandelion implementation on libp2p-pubsub**: https://github.com/rairyx/go-libp2p-pubsub/tree/dandelion +**Dandelion++ implementation on libp2p-pubsub**: https://github.com/rairyx/go-libp2p-pubsub/tree/dandelion++ ## Demo diff --git a/pubsub/raven.go b/pubsub/raven.go index da3d39a..75a4541 100644 --- a/pubsub/raven.go +++ b/pubsub/raven.go @@ -182,8 +182,6 @@ func main() { }) if bBootstrap { fmt.Println("Bootstrapper running.\nPubSub object instantiated using GossipSubRouter.\nCtrl+C to exit.") - // for true { - // } select {} } else { // Now, wait for input from the user, and send that out!