2018-11-10 17:32:45 +00:00
|
|
|
/**
|
|
|
|
* 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"
|
2019-05-10 17:07:43 +00:00
|
|
|
dhtopts "github.com/libp2p/go-libp2p-kad-dht/opts"
|
|
|
|
protocol "github.com/libp2p/go-libp2p-protocol"
|
2018-11-10 17:32:45 +00:00
|
|
|
ma "github.com/multiformats/go-multiaddr"
|
2019-01-10 04:19:33 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared/version"
|
2018-11-10 17:32:45 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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")
|
|
|
|
)
|
|
|
|
|
2019-05-10 15:56:30 +00:00
|
|
|
const dhtProtocol = "/prysm/0.0.0/dht"
|
|
|
|
|
2018-11-10 17:32:45 +00:00
|
|
|
func main() {
|
|
|
|
flag.Parse()
|
2019-01-10 04:19:33 +00:00
|
|
|
|
|
|
|
fmt.Printf("Starting bootnode. Version: %s\n", version.GetVersion())
|
|
|
|
|
2018-11-10 17:32:45 +00:00
|
|
|
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)
|
|
|
|
|
2019-05-10 15:56:30 +00:00
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
host, err := libp2p.New(ctx, opts...)
|
2018-11-10 17:32:45 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Failed to create new host. %v", err)
|
|
|
|
}
|
|
|
|
|
2019-05-10 15:56:30 +00:00
|
|
|
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)
|
|
|
|
}
|
2018-11-10 17:32:45 +00:00
|
|
|
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
|
|
|
|
}
|