prysm-pulse/tools/bootnode/bootnode.go
2019-05-10 10:07:43 -07:00

101 lines
2.4 KiB
Go

/**
* 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"
dhtopts "github.com/libp2p/go-libp2p-kad-dht/opts"
protocol "github.com/libp2p/go-libp2p-protocol"
ma "github.com/multiformats/go-multiaddr"
"github.com/prysmaticlabs/prysm/shared/version"
)
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")
)
const dhtProtocol = "/prysm/0.0.0/dht"
func main() {
flag.Parse()
fmt.Printf("Starting bootnode. Version: %s\n", version.GetVersion())
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)
ctx := context.Background()
host, err := libp2p.New(ctx, opts...)
if err != nil {
log.Fatalf("Failed to create new host. %v", err)
}
dopts := []dhtopts.Option{
dhtopts.Datastore(dsync.MutexWrap(ds.NewMapDatastore())),
dhtopts.Protocols(
protocol.ID(dhtProtocol),
),
}
dht, err := kaddht.New(ctx, host, dopts...)
if err != nil {
log.Fatalf("Failed to create new dht: %v", err)
}
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
}