mirror of https://github.com/rairyx/raven
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
4.5 KiB
Go
191 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
_ "time"
|
|
|
|
// ipfsaddr "github.com/ipfs/go-ipfs-addr"
|
|
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"
|
|
|
|
"github.com/libp2p/go-floodsub"
|
|
ma "github.com/multiformats/go-multiaddr"
|
|
)
|
|
|
|
var ho host.Host
|
|
|
|
//var dhtPtr *dht.IpfsDHT
|
|
|
|
var TopicName string = "libp2p-demo-chat"
|
|
|
|
func parseArgs() (bool, string) {
|
|
usage := fmt.Sprintf("Usage: %s [-b] [PRIVATE_KEY]\n\n-b is bootstrap mode (creates DHT)\nPRIVATE_KEY is the path to a private key like '../util/private_key.bin'\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)
|
|
}
|
|
if args[0] == "-b" {
|
|
bBootstrap = true
|
|
args = args[1:]
|
|
}
|
|
privKeyFilePath = args[0]
|
|
return bBootstrap, privKeyFilePath
|
|
}
|
|
|
|
func handleConn(conn inet.Conn) {
|
|
ctx := context.Background()
|
|
h := ho
|
|
fmt.Printf("<NOTICE> Got connection from %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")
|
|
} else {
|
|
fmt.Printf("peer mode")
|
|
}
|
|
fmt.Printf(" with private key '%s'\n", privKeyFilePath)
|
|
|
|
//
|
|
// Read the private key
|
|
//
|
|
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/9876"),
|
|
libp2p.Identity(priv),
|
|
)
|
|
} else {
|
|
host, err = libp2p.New(ctx,
|
|
libp2p.Identity(priv),
|
|
)
|
|
}
|
|
if err != nil {
|
|
fmt.Println("libp2p.New: failed: %v", err)
|
|
panic(err)
|
|
}
|
|
|
|
// ho = host
|
|
//fmt.Printf("To connect, run:\n")
|
|
//fmt.Printf("node js-dht-test/index.js %s/ipfs/%s\n", host.Addrs()[0], host.ID().Pretty())
|
|
|
|
//
|
|
// Construct a floodsub instance for this host
|
|
//
|
|
fsub, err := floodsub.NewFloodSub(ctx, host)
|
|
if err != nil {
|
|
fmt.Println("Error (floodsub.NewFloodSub): %v", err)
|
|
panic(err)
|
|
}
|
|
|
|
//
|
|
// If we are the bootstrap node, don't try to connec 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/9876/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()))
|
|
}
|
|
}()
|
|
|
|
host.Network().SetConnHandler(handleConn)
|
|
|
|
if bBootstrap {
|
|
fmt.Println("Bootstrapper running. Ctrl+C to exit.")
|
|
for true {
|
|
}
|
|
} else {
|
|
// Now, wait for input from the user, and send that out!
|
|
fmt.Println("Type something and hit enter to send to other subscribers:")
|
|
scan := bufio.NewScanner(os.Stdin)
|
|
for scan.Scan() {
|
|
if err := fsub.Publish(TopicName, scan.Bytes()); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
// //
|
|
// // Construct a DHT for peer discovery if we are the bootstrap node.
|
|
// // Else: construct a DHT client for peer discovery and connect to bootstrap node.
|
|
// //
|
|
// d, err := dht.New(ctx, host, dhtopts.Client(false))
|
|
// if err != nil {
|
|
// panic(err)
|
|
// }
|
|
|
|
// dhtPtr = d
|
|
}
|