From 82d743094edd9fc4686e71db4155eb17b23fce5d Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Sat, 10 Nov 2018 12:32:45 -0500 Subject: [PATCH] Add basic bootnode (#735) * Add basic bootnode * Add comment * fix logging --- tools/bootnode/BUILD.bazel | 23 +++++++++++ tools/bootnode/bootnode.go | 81 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 tools/bootnode/BUILD.bazel create mode 100644 tools/bootnode/bootnode.go diff --git a/tools/bootnode/BUILD.bazel b/tools/bootnode/BUILD.bazel new file mode 100644 index 0000000000..04fc4a4c15 --- /dev/null +++ b/tools/bootnode/BUILD.bazel @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go_default_library", + srcs = ["bootnode.go"], + importpath = "github.com/prysmaticlabs/prysm/tools/bootnode", + visibility = ["//visibility:private"], + deps = [ + "@com_github_ipfs_go_datastore//:go_default_library", + "@com_github_ipfs_go_datastore//sync:go_default_library", + "@com_github_ipfs_go_log//:go_default_library", + "@com_github_libp2p_go_libp2p//:go_default_library", + "@com_github_libp2p_go_libp2p_crypto//:go_default_library", + "@com_github_libp2p_go_libp2p_kad_dht//:go_default_library", + "@com_github_multiformats_go_multiaddr//:go_default_library", + ], +) + +go_binary( + name = "bootnode", + embed = [":go_default_library"], + visibility = ["//visibility:public"], +) diff --git a/tools/bootnode/bootnode.go b/tools/bootnode/bootnode.go new file mode 100644 index 0000000000..ccd09607d3 --- /dev/null +++ b/tools/bootnode/bootnode.go @@ -0,0 +1,81 @@ +/** + * Bootnode + * + * A simple peer Kademlia distributed hash table (DHT) service for peer + * discovery. The purpose of this service is to provide a starting point for + * newly connected services to find other peers outside of their network. + * + * Usage: Run bootnode --help for flag options. + */ +package main + +import ( + "context" + "flag" + "fmt" + + ds "github.com/ipfs/go-datastore" + dsync "github.com/ipfs/go-datastore/sync" + logging "github.com/ipfs/go-log" + libp2p "github.com/libp2p/go-libp2p" + crypto "github.com/libp2p/go-libp2p-crypto" + kaddht "github.com/libp2p/go-libp2p-kad-dht" + ma "github.com/multiformats/go-multiaddr" +) + +var ( + debug = flag.Bool("debug", false, "Enable debug logging") + privateKey = flag.String("private", "", "Private key to use for peer ID") + port = flag.Int("port", 4000, "Port to listen for connections") + + log = logging.Logger("prysm-bootnode") +) + +func main() { + flag.Parse() + if *debug { + logging.SetDebugLogging() + } + + listen, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", *port)) + if err != nil { + log.Fatalf("Failed to construct new multiaddress. %v", err) + } + + opts := []libp2p.Option{ + libp2p.ListenAddrs(listen), + } + opts = addPrivateKeyOpt(opts) + + host, err := libp2p.New(context.Background(), opts...) + if err != nil { + log.Fatalf("Failed to create new host. %v", err) + } + + dstore := dsync.MutexWrap(ds.NewMapDatastore()) + dht := kaddht.NewDHT(context.Background(), host, dstore) + if err := dht.Bootstrap(context.Background()); err != nil { + log.Fatalf("Failed to bootstrap DHT. %v", err) + } + + fmt.Printf("Running bootnode: /ip4/0.0.0.0/tcp/%d/p2p/%s\n", *port, host.ID().Pretty()) + + select {} +} + +func addPrivateKeyOpt(opts []libp2p.Option) []libp2p.Option { + if *privateKey != "" { + b, err := crypto.ConfigDecodeKey(*privateKey) + if err != nil { + panic(err) + } + pk, err := crypto.UnmarshalPrivateKey(b) + if err != nil { + panic(err) + } + opts = append(opts, libp2p.Identity(pk)) + } else { + log.Warning("No private key was provided. Using default/random private key") + } + return opts +}