master
go 106 lines 2.62 KB
Raw
1 package libp2p
2
3 import (
4 "fmt"
5 "sort"
6 "time"
7
8 version "github.com/ipfs/kubo"
9 config "github.com/ipfs/kubo/config"
10
11 logging "github.com/ipfs/go-log/v2"
12 "github.com/libp2p/go-libp2p"
13 "github.com/libp2p/go-libp2p/core/crypto"
14 "github.com/libp2p/go-libp2p/core/peer"
15 "github.com/libp2p/go-libp2p/core/peerstore"
16 "github.com/libp2p/go-libp2p/p2p/net/connmgr"
17 "go.uber.org/fx"
18 )
19
20 var log = logging.Logger("p2pnode")
21
22 type Libp2pOpts struct {
23 fx.Out
24
25 Opts []libp2p.Option `group:"libp2p"`
26 }
27
28 func ConnectionManager(low, high int, grace, silence time.Duration) func() (opts Libp2pOpts, err error) {
29 return func() (opts Libp2pOpts, err error) {
30 cm, err := connmgr.NewConnManager(low, high,
31 connmgr.WithGracePeriod(grace),
32 connmgr.WithSilencePeriod(silence),
33 )
34 if err != nil {
35 return opts, err
36 }
37 opts.Opts = append(opts.Opts, libp2p.ConnectionManager(cm))
38 return
39 }
40 }
41
42 func PstoreAddSelfKeys(id peer.ID, sk crypto.PrivKey, ps peerstore.Peerstore) error {
43 if err := ps.AddPubKey(id, sk.GetPublic()); err != nil {
44 return err
45 }
46
47 return ps.AddPrivKey(id, sk)
48 }
49
50 func UserAgent() func() (opts Libp2pOpts, err error) {
51 return simpleOpt(libp2p.UserAgent(version.GetUserAgentVersion()))
52 }
53
54 func simpleOpt(opt libp2p.Option) func() (opts Libp2pOpts, err error) {
55 return func() (opts Libp2pOpts, err error) {
56 opts.Opts = append(opts.Opts, opt)
57 return
58 }
59 }
60
61 type priorityOption struct {
62 priority, defaultPriority config.Priority
63 opt libp2p.Option
64 }
65
66 func prioritizeOptions(opts []priorityOption) libp2p.Option {
67 type popt struct {
68 priority int64 // lower priority values mean higher priority
69 opt libp2p.Option
70 }
71 enabledOptions := make([]popt, 0, len(opts))
72 for _, o := range opts {
73 if prio, ok := o.priority.WithDefault(o.defaultPriority); ok {
74 enabledOptions = append(enabledOptions, popt{
75 priority: prio,
76 opt: o.opt,
77 })
78 }
79 }
80 sort.Slice(enabledOptions, func(i, j int) bool {
81 return enabledOptions[i].priority < enabledOptions[j].priority
82 })
83 p2pOpts := make([]libp2p.Option, len(enabledOptions))
84 for i, opt := range enabledOptions {
85 p2pOpts[i] = opt.opt
86 }
87 return libp2p.ChainOptions(p2pOpts...)
88 }
89
90 func ForceReachability(val *config.OptionalString) func() (opts Libp2pOpts, err error) {
91 return func() (opts Libp2pOpts, err error) {
92 if val.IsDefault() {
93 return
94 }
95 v := val.WithDefault("unrecognized")
96 switch v {
97 case "public":
98 opts.Opts = append(opts.Opts, libp2p.ForceReachabilityPublic())
99 case "private":
100 opts.Opts = append(opts.Opts, libp2p.ForceReachabilityPrivate())
101 default:
102 return opts, fmt.Errorf("unrecognized reachability option: %s", v)
103 }
104 return
105 }
106 }