2017-11-04 19:06:13 +00:00
|
|
|
package libp2p
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/rand"
|
|
|
|
|
|
|
|
crypto "github.com/libp2p/go-libp2p-crypto"
|
|
|
|
host "github.com/libp2p/go-libp2p-host"
|
|
|
|
pnet "github.com/libp2p/go-libp2p-interface-pnet"
|
|
|
|
metrics "github.com/libp2p/go-libp2p-metrics"
|
|
|
|
peer "github.com/libp2p/go-libp2p-peer"
|
|
|
|
pstore "github.com/libp2p/go-libp2p-peerstore"
|
|
|
|
swarm "github.com/libp2p/go-libp2p-swarm"
|
|
|
|
transport "github.com/libp2p/go-libp2p-transport"
|
|
|
|
bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
|
|
|
mux "github.com/libp2p/go-stream-muxer"
|
|
|
|
ma "github.com/multiformats/go-multiaddr"
|
|
|
|
mplex "github.com/whyrusleeping/go-smux-multiplex"
|
|
|
|
msmux "github.com/whyrusleeping/go-smux-multistream"
|
|
|
|
yamux "github.com/whyrusleeping/go-smux-yamux"
|
|
|
|
)
|
|
|
|
|
2017-11-05 15:28:59 +00:00
|
|
|
// Config describes a set of settings for a libp2p node
|
2017-11-04 19:06:13 +00:00
|
|
|
type Config struct {
|
|
|
|
Transports []transport.Transport
|
|
|
|
Muxer mux.Transport
|
|
|
|
ListenAddrs []ma.Multiaddr
|
|
|
|
PeerKey crypto.PrivKey
|
|
|
|
Peerstore pstore.Peerstore
|
|
|
|
Protector pnet.Protector
|
|
|
|
Reporter metrics.Reporter
|
|
|
|
}
|
|
|
|
|
2017-11-05 15:28:59 +00:00
|
|
|
func New(ctx context.Context) (host.Host, error) {
|
|
|
|
return NewWithCfg(ctx, DefaultConfig())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Construct instantiates a libp2p host using information from the given
|
|
|
|
// config. `nil` may be passed to use default options.
|
|
|
|
func NewWithCfg(ctx context.Context, cfg *Config) (host.Host, error) {
|
2017-11-04 19:06:13 +00:00
|
|
|
if cfg == nil {
|
|
|
|
cfg = DefaultConfig()
|
|
|
|
}
|
|
|
|
|
2017-11-05 15:28:59 +00:00
|
|
|
// If no key was given, generate a random 2048 bit RSA key
|
2017-11-04 19:06:13 +00:00
|
|
|
if cfg.PeerKey == nil {
|
|
|
|
priv, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, rand.Reader)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
cfg.PeerKey = priv
|
|
|
|
}
|
|
|
|
|
|
|
|
// Obtain Peer ID from public key
|
|
|
|
pid, err := peer.IDFromPublicKey(cfg.PeerKey.GetPublic())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-11-05 15:28:59 +00:00
|
|
|
// Create a new blank peerstore if none was passed in
|
2017-11-04 19:06:13 +00:00
|
|
|
ps := cfg.Peerstore
|
|
|
|
if ps == nil {
|
|
|
|
ps = pstore.NewPeerstore()
|
|
|
|
}
|
|
|
|
|
|
|
|
ps.AddPrivKey(pid, cfg.PeerKey)
|
|
|
|
ps.AddPubKey(pid, cfg.PeerKey.GetPublic())
|
|
|
|
|
|
|
|
swrm, err := swarm.NewSwarmWithProtector(ctx, cfg.ListenAddrs, pid, ps, cfg.Protector, cfg.Muxer, cfg.Reporter)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
netw := (*swarm.Network)(swrm)
|
|
|
|
|
|
|
|
return bhost.New(netw), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func DefaultMuxer() mux.Transport {
|
|
|
|
// Set up stream multiplexer
|
|
|
|
tpt := msmux.NewBlankTransport()
|
2017-11-05 15:28:59 +00:00
|
|
|
|
|
|
|
// By default, support yamux and multiplex
|
2017-11-04 19:06:13 +00:00
|
|
|
tpt.AddTransport("/yamux/1.0.0", yamux.DefaultTransport)
|
|
|
|
tpt.AddTransport("/mplex/6.3.0", mplex.DefaultTransport)
|
2017-11-05 15:28:59 +00:00
|
|
|
|
2017-11-04 19:06:13 +00:00
|
|
|
return tpt
|
|
|
|
}
|
|
|
|
|
|
|
|
func DefaultConfig() *Config {
|
2017-11-05 15:28:59 +00:00
|
|
|
// Create a multiaddress that listens on a random port on all interfaces
|
|
|
|
addr, err := ma.NewMultiaddr("/ip4/0.0.0.0/tcp/0")
|
2017-11-04 19:06:13 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &Config{
|
|
|
|
ListenAddrs: []ma.Multiaddr{addr},
|
|
|
|
Peerstore: pstore.NewPeerstore(),
|
|
|
|
Muxer: DefaultMuxer(),
|
|
|
|
}
|
|
|
|
}
|