Import libp2p modules
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
This commit is contained in:
committed by
Jakub Sztandera
parent
795621ed27
commit
63627e863e
@@ -0,0 +1,25 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
type MetricsCtx context.Context
|
||||
|
||||
// LifecycleCtx creates a context which will be cancelled when lifecycle stops
|
||||
//
|
||||
// This is a hack which we need because most of our services use contexts in a
|
||||
// wrong way
|
||||
func LifecycleCtx(mctx MetricsCtx, lc fx.Lifecycle) context.Context {
|
||||
ctx, cancel := context.WithCancel(mctx)
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(_ context.Context) error {
|
||||
cancel()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
package modules
|
||||
@@ -0,0 +1,117 @@
|
||||
package libp2p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/libp2p/go-libp2p"
|
||||
host "github.com/libp2p/go-libp2p-core/host"
|
||||
p2pbhost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
mafilter "github.com/libp2p/go-maddr-filter"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
mamask "github.com/whyrusleeping/multiaddr-filter"
|
||||
)
|
||||
|
||||
func AddrFilters(filters []string) func() (opts Libp2pOpts, err error) {
|
||||
return func() (opts Libp2pOpts, err error) {
|
||||
for _, s := range filters {
|
||||
f, err := mamask.NewMask(s)
|
||||
if err != nil {
|
||||
return opts, fmt.Errorf("incorrectly formatted address filter in config: %s", s)
|
||||
}
|
||||
opts.Opts = append(opts.Opts, libp2p.FilterAddresses(f))
|
||||
}
|
||||
return opts, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeAddrsFactory(announce []string, noAnnounce []string) (p2pbhost.AddrsFactory, error) {
|
||||
var annAddrs []ma.Multiaddr
|
||||
for _, addr := range announce {
|
||||
maddr, err := ma.NewMultiaddr(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
annAddrs = append(annAddrs, maddr)
|
||||
}
|
||||
|
||||
filters := mafilter.NewFilters()
|
||||
noAnnAddrs := map[string]bool{}
|
||||
for _, addr := range noAnnounce {
|
||||
f, err := mamask.NewMask(addr)
|
||||
if err == nil {
|
||||
filters.AddFilter(*f, mafilter.ActionDeny)
|
||||
continue
|
||||
}
|
||||
maddr, err := ma.NewMultiaddr(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
noAnnAddrs[string(maddr.Bytes())] = true
|
||||
}
|
||||
|
||||
return func(allAddrs []ma.Multiaddr) []ma.Multiaddr {
|
||||
var addrs []ma.Multiaddr
|
||||
if len(annAddrs) > 0 {
|
||||
addrs = annAddrs
|
||||
} else {
|
||||
addrs = allAddrs
|
||||
}
|
||||
|
||||
var out []ma.Multiaddr
|
||||
for _, maddr := range addrs {
|
||||
// check for exact matches
|
||||
ok := noAnnAddrs[string(maddr.Bytes())]
|
||||
// check for /ipcidr matches
|
||||
if !ok && !filters.AddrBlocked(maddr) {
|
||||
out = append(out, maddr)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}, nil
|
||||
}
|
||||
|
||||
func AddrsFactory(announce []string, noAnnounce []string) func() (opts Libp2pOpts, err error) {
|
||||
return func() (opts Libp2pOpts, err error) {
|
||||
addrsFactory, err := makeAddrsFactory(announce, noAnnounce)
|
||||
if err != nil {
|
||||
return opts, err
|
||||
}
|
||||
opts.Opts = append(opts.Opts, libp2p.AddrsFactory(addrsFactory))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func listenAddresses(addresses []string) ([]ma.Multiaddr, error) {
|
||||
var listen []ma.Multiaddr
|
||||
for _, addr := range addresses {
|
||||
maddr, err := ma.NewMultiaddr(addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failure to parse config.Addresses.Swarm: %s", addresses)
|
||||
}
|
||||
listen = append(listen, maddr)
|
||||
}
|
||||
|
||||
return listen, nil
|
||||
}
|
||||
|
||||
func StartListening(addresses []string) func(host host.Host) error {
|
||||
return func(host host.Host) error {
|
||||
listenAddrs, err := listenAddresses(addresses)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Actually start listening:
|
||||
if err := host.Network().Listen(listenAddrs...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// list out our addresses
|
||||
addrs, err := host.Network().InterfaceListenAddresses()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("Swarm listening at: %s", addrs)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package libp2p
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p/p2p/discovery"
|
||||
"go.uber.org/fx"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/node/modules/helpers"
|
||||
)
|
||||
|
||||
const discoveryConnTimeout = time.Second * 30
|
||||
|
||||
type discoveryHandler struct {
|
||||
ctx context.Context
|
||||
host host.Host
|
||||
}
|
||||
|
||||
func (dh *discoveryHandler) HandlePeerFound(p peer.AddrInfo) {
|
||||
log.Warning("trying peer info: ", p)
|
||||
ctx, cancel := context.WithTimeout(dh.ctx, discoveryConnTimeout)
|
||||
defer cancel()
|
||||
if err := dh.host.Connect(ctx, p); err != nil {
|
||||
log.Warning("Failed to connect to peer found by discovery: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func DiscoveryHandler(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) *discoveryHandler {
|
||||
return &discoveryHandler{
|
||||
ctx: helpers.LifecycleCtx(mctx, lc),
|
||||
host: host,
|
||||
}
|
||||
}
|
||||
|
||||
func SetupDiscovery(mdns bool, mdnsInterval int) func(helpers.MetricsCtx, fx.Lifecycle, host.Host, *discoveryHandler) error {
|
||||
return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, handler *discoveryHandler) error {
|
||||
if mdns {
|
||||
if mdnsInterval == 0 {
|
||||
mdnsInterval = 5
|
||||
}
|
||||
service, err := discovery.NewMdnsService(helpers.LifecycleCtx(mctx, lc), host, time.Duration(mdnsInterval)*time.Second, discovery.ServiceTag)
|
||||
if err != nil {
|
||||
log.Error("mdns error: ", err)
|
||||
return nil
|
||||
}
|
||||
service.RegisterNotifee(handler)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package libp2p
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ipfs/go-datastore"
|
||||
nilrouting "github.com/ipfs/go-ipfs-routing/none"
|
||||
"github.com/libp2p/go-libp2p"
|
||||
host "github.com/libp2p/go-libp2p-core/host"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
peerstore "github.com/libp2p/go-libp2p-core/peerstore"
|
||||
dht "github.com/libp2p/go-libp2p-kad-dht"
|
||||
dhtopts "github.com/libp2p/go-libp2p-kad-dht/opts"
|
||||
record "github.com/libp2p/go-libp2p-record"
|
||||
routedhost "github.com/libp2p/go-libp2p/p2p/host/routed"
|
||||
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
|
||||
"go.uber.org/fx"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/node/modules/helpers"
|
||||
)
|
||||
|
||||
type P2PHostIn struct {
|
||||
fx.In
|
||||
|
||||
ID peer.ID
|
||||
Peerstore peerstore.Peerstore
|
||||
|
||||
Opts [][]libp2p.Option `group:"libp2p"`
|
||||
}
|
||||
|
||||
// ////////////////////////
|
||||
|
||||
type RawHost host.Host
|
||||
|
||||
func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (RawHost, error) {
|
||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||
|
||||
pkey := params.Peerstore.PrivKey(params.ID)
|
||||
if pkey == nil {
|
||||
return nil, fmt.Errorf("missing private key for node ID: %s", params.ID.Pretty())
|
||||
}
|
||||
|
||||
opts := []libp2p.Option{libp2p.Identity(pkey), libp2p.Peerstore(params.Peerstore), libp2p.NoListenAddrs}
|
||||
for _, o := range params.Opts {
|
||||
opts = append(opts, o...)
|
||||
}
|
||||
|
||||
h, err := libp2p.New(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return h.Close()
|
||||
},
|
||||
})
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func MockHost(mn mocknet.Mocknet, id peer.ID, ps peerstore.Peerstore) (RawHost, error) {
|
||||
return mn.AddPeerWithPeerstore(id, ps)
|
||||
}
|
||||
|
||||
func DHTRouting(client bool) interface{} {
|
||||
return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host RawHost, dstore datastore.Batching, validator record.Validator) (BaseIpfsRouting, error) {
|
||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||
|
||||
d, err := dht.New(
|
||||
ctx, host,
|
||||
dhtopts.Client(client),
|
||||
dhtopts.Datastore(dstore),
|
||||
dhtopts.Validator(validator),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return d.Close()
|
||||
},
|
||||
})
|
||||
|
||||
return d, nil
|
||||
}
|
||||
}
|
||||
|
||||
func NilRouting(mctx helpers.MetricsCtx) (BaseIpfsRouting, error) {
|
||||
return nilrouting.ConstructNilRouting(mctx, nil, nil, nil)
|
||||
}
|
||||
|
||||
func RoutedHost(rh RawHost, r BaseIpfsRouting) host.Host {
|
||||
return routedhost.Wrap(rh, r)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package libp2p
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p-connmgr"
|
||||
"github.com/libp2p/go-libp2p-core/crypto"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p-core/peerstore"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
var log = logging.Logger("p2pnode")
|
||||
|
||||
type Libp2pOpts struct {
|
||||
fx.Out
|
||||
|
||||
Opts []libp2p.Option `group:"libp2p"`
|
||||
}
|
||||
|
||||
// Misc options
|
||||
|
||||
func ConnectionManager(low, high int, grace time.Duration) func() (opts Libp2pOpts, err error) {
|
||||
return func() (opts Libp2pOpts, err error) {
|
||||
cm := connmgr.NewConnManager(low, high, grace)
|
||||
opts.Opts = append(opts.Opts, libp2p.ConnectionManager(cm))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func PstoreAddSelfKeys(id peer.ID, sk crypto.PrivKey, ps peerstore.Peerstore) error {
|
||||
if err := ps.AddPubKey(id, sk.GetPublic()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ps.AddPrivKey(id, sk)
|
||||
}
|
||||
|
||||
func simpleOpt(opt libp2p.Option) func() (opts Libp2pOpts, err error) {
|
||||
return func() (opts Libp2pOpts, err error) {
|
||||
opts.Opts = append(opts.Opts, opt)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package libp2p
|
||||
|
||||
/*import (
|
||||
"github.com/libp2p/go-libp2p"
|
||||
autonat "github.com/libp2p/go-libp2p-autonat-svc"
|
||||
host "github.com/libp2p/go-libp2p-core/host"
|
||||
libp2pquic "github.com/libp2p/go-libp2p-quic-transport"
|
||||
"go.uber.org/fx"
|
||||
|
||||
"github.com/ipfs/go-ipfs/repo"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/node/modules/helpers"
|
||||
)
|
||||
|
||||
var NatPortMap = simpleOpt(libp2p.NATPortMap())
|
||||
|
||||
func AutoNATService(quic bool) func(repo repo.Repo, mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) error {
|
||||
return func(repo repo.Repo, mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) error {
|
||||
// collect private net option in case swarm.key is presented
|
||||
opts, _, err := PNet(repo)
|
||||
if err != nil {
|
||||
// swarm key exists but was failed to decode
|
||||
return err
|
||||
}
|
||||
|
||||
if quic {
|
||||
opts.Opts = append(opts.Opts, libp2p.DefaultTransports, libp2p.Transport(libp2pquic.NewTransport))
|
||||
}
|
||||
|
||||
_, err = autonat.NewAutoNATService(helpers.LifecycleCtx(mctx, lc), host, opts.Opts...)
|
||||
return err
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,71 @@
|
||||
package libp2p
|
||||
|
||||
/*import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p"
|
||||
host "github.com/libp2p/go-libp2p-core/host"
|
||||
pnet "github.com/libp2p/go-libp2p-pnet"
|
||||
"go.uber.org/fx"
|
||||
|
||||
"github.com/ipfs/go-ipfs/repo"
|
||||
)
|
||||
|
||||
type PNetFingerprint []byte
|
||||
|
||||
func PNet(repo repo.Repo) (opts Libp2pOpts, fp PNetFingerprint, err error) {
|
||||
swarmkey, err := repo.SwarmKey()
|
||||
if err != nil || swarmkey == nil {
|
||||
return opts, nil, err
|
||||
}
|
||||
|
||||
protec, err := pnet.NewProtector(bytes.NewReader(swarmkey))
|
||||
if err != nil {
|
||||
return opts, nil, fmt.Errorf("failed to configure private network: %s", err)
|
||||
}
|
||||
fp = protec.Fingerprint()
|
||||
|
||||
opts.Opts = append(opts.Opts, libp2p.PrivateNetwork(protec))
|
||||
return opts, fp, nil
|
||||
}
|
||||
|
||||
func PNetChecker(repo repo.Repo, ph host.Host, lc fx.Lifecycle) error {
|
||||
// TODO: better check?
|
||||
swarmkey, err := repo.SwarmKey()
|
||||
if err != nil || swarmkey == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(_ context.Context) error {
|
||||
go func() {
|
||||
t := time.NewTicker(30 * time.Second)
|
||||
defer t.Stop()
|
||||
|
||||
<-t.C // swallow one tick
|
||||
for {
|
||||
select {
|
||||
case <-t.C:
|
||||
if len(ph.Network().Peers()) == 0 {
|
||||
log.Warning("We are in private network and have no peers.")
|
||||
log.Warning("This might be configuration mistake.")
|
||||
}
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
},
|
||||
OnStop: func(_ context.Context) error {
|
||||
close(done)
|
||||
return nil
|
||||
},
|
||||
})
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,21 @@
|
||||
package libp2p
|
||||
|
||||
import (
|
||||
host "github.com/libp2p/go-libp2p-core/host"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
"go.uber.org/fx"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/node/modules/helpers"
|
||||
)
|
||||
|
||||
func FloodSub(pubsubOptions ...pubsub.Option) interface{} {
|
||||
return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) (service *pubsub.PubSub, err error) {
|
||||
return pubsub.NewFloodSub(helpers.LifecycleCtx(mctx, lc), host, pubsubOptions...)
|
||||
}
|
||||
}
|
||||
|
||||
func GossipSub(pubsubOptions ...pubsub.Option) interface{} {
|
||||
return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) (service *pubsub.PubSub, err error) {
|
||||
return pubsub.NewGossipSub(helpers.LifecycleCtx(mctx, lc), host, pubsubOptions...)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package libp2p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/libp2p/go-libp2p"
|
||||
circuit "github.com/libp2p/go-libp2p-circuit"
|
||||
coredisc "github.com/libp2p/go-libp2p-core/discovery"
|
||||
routing "github.com/libp2p/go-libp2p-core/routing"
|
||||
discovery "github.com/libp2p/go-libp2p-discovery"
|
||||
basichost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
relay "github.com/libp2p/go-libp2p/p2p/host/relay"
|
||||
"go.uber.org/fx"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/node/modules/helpers"
|
||||
)
|
||||
|
||||
func Relay(disable, enableHop bool) func() (opts Libp2pOpts, err error) {
|
||||
return func() (opts Libp2pOpts, err error) {
|
||||
if disable {
|
||||
// Enabled by default.
|
||||
opts.Opts = append(opts.Opts, libp2p.DisableRelay())
|
||||
} else {
|
||||
relayOpts := []circuit.RelayOpt{circuit.OptDiscovery}
|
||||
if enableHop {
|
||||
relayOpts = append(relayOpts, circuit.OptHop)
|
||||
}
|
||||
opts.Opts = append(opts.Opts, libp2p.EnableRelay(relayOpts...))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: should be use baseRouting or can we use higher level router here?
|
||||
func Discovery(router BaseIpfsRouting) (coredisc.Discovery, error) {
|
||||
crouter, ok := router.(routing.ContentRouting)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no suitable routing for discovery")
|
||||
}
|
||||
|
||||
return discovery.NewRoutingDiscovery(crouter), nil
|
||||
}
|
||||
|
||||
// NOTE: only set when relayHop is set
|
||||
func AdvertiseRelay(mctx helpers.MetricsCtx, d coredisc.Discovery) {
|
||||
relay.Advertise(mctx, d)
|
||||
}
|
||||
|
||||
// NOTE: only set when relayHop is not set
|
||||
func AutoRelay(mctx helpers.MetricsCtx, lc fx.Lifecycle, router BaseIpfsRouting, h RawHost, d coredisc.Discovery) error {
|
||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||
|
||||
// TODO: review: LibP2P doesn't set this as host in config.go, why?
|
||||
_ = relay.NewAutoRelay(ctx, h.(*basichost.BasicHost), d, router)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package libp2p
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
|
||||
routing "github.com/libp2p/go-libp2p-core/routing"
|
||||
dht "github.com/libp2p/go-libp2p-kad-dht"
|
||||
record "github.com/libp2p/go-libp2p-record"
|
||||
routinghelpers "github.com/libp2p/go-libp2p-routing-helpers"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
type BaseIpfsRouting routing.Routing
|
||||
|
||||
type Router struct {
|
||||
routing.Routing
|
||||
|
||||
Priority int // less = more important
|
||||
}
|
||||
|
||||
type p2pRouterOut struct {
|
||||
fx.Out
|
||||
|
||||
Router Router `group:"routers"`
|
||||
}
|
||||
|
||||
func BaseRouting(lc fx.Lifecycle, in BaseIpfsRouting) (out p2pRouterOut, dr *dht.IpfsDHT) {
|
||||
if dht, ok := in.(*dht.IpfsDHT); ok {
|
||||
dr = dht
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return dr.Close()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return p2pRouterOut{
|
||||
Router: Router{
|
||||
Priority: 1000,
|
||||
Routing: in,
|
||||
},
|
||||
}, dr
|
||||
}
|
||||
|
||||
type p2pOnlineRoutingIn struct {
|
||||
fx.In
|
||||
|
||||
Routers []Router `group:"routers"`
|
||||
Validator record.Validator
|
||||
}
|
||||
|
||||
func Routing(in p2pOnlineRoutingIn) routing.Routing {
|
||||
routers := in.Routers
|
||||
|
||||
sort.SliceStable(routers, func(i, j int) bool {
|
||||
return routers[i].Priority < routers[j].Priority
|
||||
})
|
||||
|
||||
irouters := make([]routing.Routing, len(routers))
|
||||
for i, v := range routers {
|
||||
irouters[i] = v.Routing
|
||||
}
|
||||
|
||||
return routinghelpers.Tiered{
|
||||
Routers: irouters,
|
||||
Validator: in.Validator,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package libp2p
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/libp2p/go-libp2p"
|
||||
smux "github.com/libp2p/go-libp2p-core/mux"
|
||||
mplex "github.com/libp2p/go-libp2p-mplex"
|
||||
yamux "github.com/libp2p/go-libp2p-yamux"
|
||||
)
|
||||
|
||||
func makeSmuxTransportOption(mplexExp bool) libp2p.Option {
|
||||
const yamuxID = "/yamux/1.0.0"
|
||||
const mplexID = "/mplex/6.7.0"
|
||||
|
||||
ymxtpt := *yamux.DefaultTransport
|
||||
ymxtpt.AcceptBacklog = 512
|
||||
|
||||
if os.Getenv("YAMUX_DEBUG") != "" {
|
||||
ymxtpt.LogOutput = os.Stderr
|
||||
}
|
||||
|
||||
muxers := map[string]smux.Multiplexer{yamuxID: &ymxtpt}
|
||||
if mplexExp {
|
||||
muxers[mplexID] = mplex.DefaultTransport
|
||||
}
|
||||
|
||||
// Allow muxer preference order overriding
|
||||
order := []string{yamuxID, mplexID}
|
||||
if prefs := os.Getenv("LIBP2P_MUX_PREFS"); prefs != "" {
|
||||
order = strings.Fields(prefs)
|
||||
}
|
||||
|
||||
opts := make([]libp2p.Option, 0, len(order))
|
||||
for _, id := range order {
|
||||
tpt, ok := muxers[id]
|
||||
if !ok {
|
||||
log.Warning("unknown or duplicate muxer in LIBP2P_MUX_PREFS: %s", id)
|
||||
continue
|
||||
}
|
||||
delete(muxers, id)
|
||||
opts = append(opts, libp2p.Muxer(id, tpt))
|
||||
}
|
||||
|
||||
return libp2p.ChainOptions(opts...)
|
||||
}
|
||||
|
||||
func SmuxTransport(mplex bool) func() (opts Libp2pOpts, err error) {
|
||||
return func() (opts Libp2pOpts, err error) {
|
||||
opts.Opts = append(opts.Opts, makeSmuxTransportOption(mplex))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package libp2p
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
libp2pquic "github.com/libp2p/go-libp2p-quic-transport"
|
||||
secio "github.com/libp2p/go-libp2p-secio"
|
||||
tls "github.com/libp2p/go-libp2p-tls"
|
||||
)
|
||||
|
||||
var DefaultTransports = simpleOpt(libp2p.DefaultTransports)
|
||||
var QUIC = simpleOpt(libp2p.Transport(libp2pquic.NewTransport))
|
||||
|
||||
func Security(enabled, preferTLS bool) interface{} {
|
||||
if !enabled {
|
||||
return func() (opts Libp2pOpts) {
|
||||
// TODO: shouldn't this be Errorf to guarantee visibility?
|
||||
log.Warningf(`Your IPFS node has been configured to run WITHOUT ENCRYPTED CONNECTIONS.
|
||||
You will not be able to connect to any nodes configured to use encrypted connections`)
|
||||
opts.Opts = append(opts.Opts, libp2p.NoSecurity)
|
||||
return opts
|
||||
}
|
||||
}
|
||||
return func() (opts Libp2pOpts) {
|
||||
if preferTLS {
|
||||
opts.Opts = append(opts.Opts, libp2p.ChainOptions(libp2p.Security(tls.ID, tls.New), libp2p.Security(secio.ID, secio.New)))
|
||||
} else {
|
||||
opts.Opts = append(opts.Opts, libp2p.ChainOptions(libp2p.Security(secio.ID, secio.New), libp2p.Security(tls.ID, tls.New)))
|
||||
}
|
||||
return opts
|
||||
}
|
||||
}
|
||||
|
||||
func BandwidthCounter() (opts Libp2pOpts, reporter metrics.Reporter) {
|
||||
reporter = metrics.NewBandwidthCounter()
|
||||
opts.Opts = append(opts.Opts, libp2p.BandwidthReporter(reporter))
|
||||
return opts, reporter
|
||||
}
|
||||
Reference in New Issue
Block a user